#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, delayed_insert::tables_in_use, and delayed_insert::thd.
Referenced by mysql_insert().
01757 { 01758 DBUG_ENTER("end_delayed_insert"); 01759 delayed_insert *di=thd->di; 01760 pthread_mutex_lock(&di->mutex); 01761 DBUG_PRINT("info",("tables in use: %d",di->tables_in_use)); 01762 if (!--di->tables_in_use || di->thd.killed) 01763 { // Unlock table 01764 di->status=1; 01765 pthread_cond_signal(&di->cond); 01766 } 01767 pthread_mutex_unlock(&di->mutex); 01768 DBUG_VOID_RETURN; 01769 }
Here is the caller graph for this function:

| delayed_insert* find_handler | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 1436 of file sql_insert.cc.
References st_table_list::db, delayed_threads, delayed_insert::lock(), LOCK_delayed_insert, pthread_mutex_lock, pthread_mutex_unlock, st_table::s, LEX_STRING::str, strcmp(), delayed_insert::table, st_table_share::table_name, st_table_list::table_name, and delayed_insert::thd.
Referenced by delayed_get_table().
01437 { 01438 thd->proc_info="waiting for delay_list"; 01439 pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list 01440 I_List_iterator<delayed_insert> it(delayed_threads); 01441 delayed_insert *tmp; 01442 while ((tmp=it++)) 01443 { 01444 if (!strcmp(tmp->thd.db, table_list->db) && 01445 !strcmp(table_list->table_name, tmp->table->s->table_name.str)) 01446 { 01447 tmp->lock(); 01448 break; 01449 } 01450 } 01451 pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list 01452 return tmp; 01453 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void free_delayed_insert_blobs | ( | register TABLE * | table | ) | [static] |
Definition at line 2046 of file sql_insert.cc.
References BLOB_FLAG, MY_ALLOW_ZERO_PTR, my_free, and MYF.
Referenced by delayed_insert::handle_inserts().
02047 { 02048 for (Field **ptr=table->field ; *ptr ; ptr++) 02049 { 02050 if ((*ptr)->flags & BLOB_FLAG) 02051 { 02052 char *str; 02053 ((Field_blob *) (*ptr))->get_ptr(&str); 02054 my_free(str,MYF(MY_ALLOW_ZERO_PTR)); 02055 ((Field_blob *) (*ptr))->reset(); 02056 } 02057 } 02058 }
Here is the caller graph for this function:

| pthread_handler_t handle_delayed_insert | ( | void * | arg | ) |
Definition at line 1812 of file sql_insert.cc.
References abort_loop, delayed_insert::cond, delayed_insert::cond_client, st_table::copy_blobs, DBUG_ENTER, DBUG_PRINT, delayed_insert::dead, delayed_insert_timeout, delayed_threads, ER, ER_ILLEGAL_HA, ER_OUT_OF_RESOURCES, err, error, ETIME, st_table::file, delayed_insert::group_count, HA_CAN_INSERT_DELAYED, handler::ha_release_auto_increment(), handler::ha_table_flags(), delayed_insert::handle_inserts(), init_thr_lock(), KILL_CONNECTION, lock, delayed_insert::lock_count(), LOCK_delayed_insert, LOCK_thread_count, delayed_insert::mutex, my_error(), my_thread_init(), MYF, mysql_lock_tables(), mysql_unlock_tables(), open_ltable(), pthread_detach_this_thread, pthread_mutex_lock, pthread_mutex_unlock, set_timespec, sigemptyset, delayed_insert::stacked_inserts, delayed_insert::status, strmov(), delayed_insert::table, delayed_insert::table_list, st_table_list::table_name, delayed_insert::tables_in_use, delayed_insert::thd, thread_id, threads, TL_WRITE_DELAYED, ilink::unlink(), and VOID.
Referenced by delayed_get_table().
01813 { 01814 delayed_insert *di=(delayed_insert*) arg; 01815 THD *thd= &di->thd; 01816 01817 pthread_detach_this_thread(); 01818 /* Add thread to THD list so that's it's visible in 'show processlist' */ 01819 pthread_mutex_lock(&LOCK_thread_count); 01820 thd->thread_id=thread_id++; 01821 thd->end_time(); 01822 threads.append(thd); 01823 thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; 01824 pthread_mutex_unlock(&LOCK_thread_count); 01825 01826 /* 01827 Wait until the client runs into pthread_cond_wait(), 01828 where we free it after the table is opened and di linked in the list. 01829 If we did not wait here, the client might detect the opened table 01830 before it is linked to the list. It would release LOCK_delayed_create 01831 and allow another thread to create another handler for the same table, 01832 since it does not find one in the list. 01833 */ 01834 pthread_mutex_lock(&di->mutex); 01835 #if !defined( __WIN__) /* Win32 calls this in pthread_create */ 01836 if (my_thread_init()) 01837 { 01838 strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES)); 01839 goto end; 01840 } 01841 #endif 01842 01843 DBUG_ENTER("handle_delayed_insert"); 01844 thd->thread_stack= (char*) &thd; 01845 if (init_thr_lock() || thd->store_globals()) 01846 { 01847 thd->fatal_error(); 01848 strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES)); 01849 goto err; 01850 } 01851 #if !defined(__WIN__) && !defined(__NETWARE__) 01852 sigset_t set; 01853 VOID(sigemptyset(&set)); // Get mask in use 01854 VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); 01855 #endif 01856 01857 /* open table */ 01858 01859 if (!(di->table=open_ltable(thd,&di->table_list,TL_WRITE_DELAYED))) 01860 { 01861 thd->fatal_error(); // Abort waiting inserts 01862 goto err; 01863 } 01864 if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED)) 01865 { 01866 thd->fatal_error(); 01867 my_error(ER_ILLEGAL_HA, MYF(0), di->table_list.table_name); 01868 goto err; 01869 } 01870 di->table->copy_blobs=1; 01871 01872 /* One can now use this */ 01873 pthread_mutex_lock(&LOCK_delayed_insert); 01874 delayed_threads.append(di); 01875 pthread_mutex_unlock(&LOCK_delayed_insert); 01876 01877 /* Tell client that the thread is initialized */ 01878 pthread_cond_signal(&di->cond_client); 01879 01880 /* Now wait until we get an insert or lock to handle */ 01881 /* We will not abort as long as a client thread uses this thread */ 01882 01883 for (;;) 01884 { 01885 if (thd->killed == THD::KILL_CONNECTION) 01886 { 01887 uint lock_count; 01888 /* 01889 Remove this from delay insert list so that no one can request a 01890 table from this 01891 */ 01892 pthread_mutex_unlock(&di->mutex); 01893 pthread_mutex_lock(&LOCK_delayed_insert); 01894 di->unlink(); 01895 lock_count=di->lock_count(); 01896 pthread_mutex_unlock(&LOCK_delayed_insert); 01897 pthread_mutex_lock(&di->mutex); 01898 if (!lock_count && !di->tables_in_use && !di->stacked_inserts) 01899 break; // Time to die 01900 } 01901 01902 if (!di->status && !di->stacked_inserts) 01903 { 01904 struct timespec abstime; 01905 set_timespec(abstime, delayed_insert_timeout); 01906 01907 /* Information for pthread_kill */ 01908 di->thd.mysys_var->current_mutex= &di->mutex; 01909 di->thd.mysys_var->current_cond= &di->cond; 01910 di->thd.proc_info="Waiting for INSERT"; 01911 01912 DBUG_PRINT("info",("Waiting for someone to insert rows")); 01913 while (!thd->killed) 01914 { 01915 int error; 01916 #if defined(HAVE_BROKEN_COND_TIMEDWAIT) 01917 error=pthread_cond_wait(&di->cond,&di->mutex); 01918 #else 01919 error=pthread_cond_timedwait(&di->cond,&di->mutex,&abstime); 01920 #ifdef EXTRA_DEBUG 01921 if (error && error != EINTR && error != ETIMEDOUT) 01922 { 01923 fprintf(stderr, "Got error %d from pthread_cond_timedwait\n",error); 01924 DBUG_PRINT("error",("Got error %d from pthread_cond_timedwait", 01925 error)); 01926 } 01927 #endif 01928 #endif 01929 if (thd->killed || di->status) 01930 break; 01931 if (error == ETIMEDOUT || error == ETIME) 01932 { 01933 thd->killed= THD::KILL_CONNECTION; 01934 break; 01935 } 01936 } 01937 /* We can't lock di->mutex and mysys_var->mutex at the same time */ 01938 pthread_mutex_unlock(&di->mutex); 01939 pthread_mutex_lock(&di->thd.mysys_var->mutex); 01940 di->thd.mysys_var->current_mutex= 0; 01941 di->thd.mysys_var->current_cond= 0; 01942 pthread_mutex_unlock(&di->thd.mysys_var->mutex); 01943 pthread_mutex_lock(&di->mutex); 01944 } 01945 di->thd.proc_info=0; 01946 01947 if (di->tables_in_use && ! thd->lock) 01948 { 01949 bool not_used; 01950 /* 01951 Request for new delayed insert. 01952 Lock the table, but avoid to be blocked by a global read lock. 01953 If we got here while a global read lock exists, then one or more 01954 inserts started before the lock was requested. These are allowed 01955 to complete their work before the server returns control to the 01956 client which requested the global read lock. The delayed insert 01957 handler will close the table and finish when the outstanding 01958 inserts are done. 01959 */ 01960 if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, 01961 MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK, 01962 ¬_used))) 01963 { 01964 /* Fatal error */ 01965 di->dead= 1; 01966 thd->killed= THD::KILL_CONNECTION; 01967 } 01968 pthread_cond_broadcast(&di->cond_client); 01969 } 01970 if (di->stacked_inserts) 01971 { 01972 if (di->handle_inserts()) 01973 { 01974 /* Some fatal error */ 01975 di->dead= 1; 01976 thd->killed= THD::KILL_CONNECTION; 01977 } 01978 } 01979 di->status=0; 01980 if (!di->stacked_inserts && !di->tables_in_use && thd->lock) 01981 { 01982 /* 01983 No one is doing a insert delayed 01984 Unlock table so that other threads can use it 01985 */ 01986 MYSQL_LOCK *lock=thd->lock; 01987 thd->lock=0; 01988 pthread_mutex_unlock(&di->mutex); 01989 di->table->file->ha_release_auto_increment(); 01990 mysql_unlock_tables(thd, lock); 01991 di->group_count=0; 01992 pthread_mutex_lock(&di->mutex); 01993 } 01994 if (di->tables_in_use) 01995 pthread_cond_broadcast(&di->cond_client); // If waiting clients 01996 } 01997 01998 err: 01999 /* 02000 mysql_lock_tables() can potentially start a transaction and write 02001 a table map. In the event of an error, that transaction has to be 02002 rolled back. We only need to roll back a potential statement 02003 transaction, since real transactions are rolled back in 02004 close_thread_tables(). 02005 */ 02006 ha_rollback_stmt(thd); 02007 02008 end: 02009 /* 02010 di should be unlinked from the thread handler list and have no active 02011 clients 02012 */ 02013 02014 close_thread_tables(thd); // Free the table 02015 di->table=0; 02016 di->dead= 1; // If error 02017 thd->killed= THD::KILL_CONNECTION; // If error 02018 pthread_cond_broadcast(&di->cond_client); // Safety 02019 pthread_mutex_unlock(&di->mutex); 02020 02021 pthread_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table 02022 pthread_mutex_lock(&LOCK_delayed_insert); 02023 delete di; 02024 pthread_mutex_unlock(&LOCK_delayed_insert); 02025 pthread_mutex_unlock(&LOCK_delayed_create); 02026 02027 my_thread_end(); 02028 pthread_exit(0); 02029 DBUG_RETURN(0); 02030 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void kill_delayed_threads | ( | void | ) |
Definition at line 1774 of file sql_insert.cc.
References delayed_threads, KILL_CONNECTION, LOCK_delayed_insert, delayed_insert::mutex, pthread_mutex_lock, pthread_mutex_unlock, delayed_insert::thd, and VOID.
Referenced by close_cached_tables().
01775 { 01776 VOID(pthread_mutex_lock(&LOCK_delayed_insert)); // For unlink from list 01777 01778 I_List_iterator<delayed_insert> it(delayed_threads); 01779 delayed_insert *tmp; 01780 while ((tmp=it++)) 01781 { 01782 /* Ensure that the thread doesn't kill itself while we are looking at it */ 01783 pthread_mutex_lock(&tmp->mutex); 01784 tmp->thd.killed= THD::KILL_CONNECTION; 01785 if (tmp->thd.mysys_var) 01786 { 01787 pthread_mutex_lock(&tmp->thd.mysys_var->mutex); 01788 if (tmp->thd.mysys_var->current_cond) 01789 { 01790 /* 01791 We need the following test because the main mutex may be locked 01792 in handle_delayed_insert() 01793 */ 01794 if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) 01795 pthread_mutex_lock(tmp->thd.mysys_var->current_mutex); 01796 pthread_cond_broadcast(tmp->thd.mysys_var->current_cond); 01797 if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) 01798 pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex); 01799 } 01800 pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); 01801 } 01802 pthread_mutex_unlock(&tmp->mutex); 01803 } 01804 VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list 01805 }
Here is the caller graph for this function:

Definition at line 980 of file sql_insert.cc.
References st_key::flags, HA_NOSAME, and st_table::key_info.
Referenced by write_record().
00981 { 00982 while (++keynr < table->s->keys) 00983 if (table->key_info[keynr].flags & HA_NOSAME) 00984 return 0; 00985 return 1; 00986 }
Here is the caller graph for this function:

| 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 | |||
| ) |
Definition at line 293 of file sql_insert.cc.
References abort(), CHECK_FIELD_ERROR_FOR_NULL, CHECK_FIELD_IGNORE, CHECK_FIELD_WARN, check_that_all_fields_are_given_values(), st_copy_info::copied, counter, st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, st_table_share::default_values, delayed_get_table(), st_copy_info::deleted, st_table_list::derived, DUP_ERROR, DUP_REPLACE, DUP_UPDATE, base_list::elements, end_delayed_insert(), ER, ER_DELAYED_INSERT_TABLE_LOCKED, ER_INSERT_INFO, ER_WRONG_VALUE_COUNT_ON_ROW, error, handler::extra(), FALSE, st_table::field, st_table::file, fill_record_n_invoke_before_triggers(), find_locked_table(), st_table::found_next_number_field, free_underlaid_joins(), ha_autocommit_or_rollback(), handler::ha_end_bulk_insert(), HA_EXTRA_IGNORE_DUP_KEY, HA_EXTRA_NO_IGNORE_DUP_KEY, HA_EXTRA_WRITE_CAN_REPLACE, HA_EXTRA_WRITE_CANNOT_REPLACE, handler::ha_release_auto_increment(), handler::ha_start_bulk_insert(), st_copy_info::handle_duplicates, Table_triggers_list::has_delete_triggers(), handler::has_transactions(), id, st_copy_info::ignore, info, MYSQL_LOG::is_open(), st_table_list::lock_type, st_table::mark_columns_needed_for_insert(), MARK_COLUMNS_READ, MODE_STRICT_ALL_TABLES, MODE_STRICT_TRANS_TABLES, my_errno, my_error(), MYF, mysql_bin_log, mysql_prepare_insert(), mysql_unlock_tables(), st_table_list::next_global, st_table_list::next_local, st_table::next_number_field, NULL, open_and_lock_tables(), OPTION_BIN_LOG, OPTION_STATUS_NO_TRANS_UPDATE, OPTION_WARNINGS, st_table_list::prepare_check_option(), st_table_list::prepare_where(), handler::print_error(), st_table::record, st_copy_info::records, Name_resolution_context::resolve_in_table_list_only(), restore_record, Name_resolution_context_state::restore_state(), List_iterator_fast< T >::rewind(), st_table::s, Name_resolution_context_state::save_state(), Name_resolution_context::select_lex, send_ok(), setup_fields(), SPECIAL_NO_NEW_FUNC, SPECIAL_SAFE_MODE, specialflag, SUPER_ACL, st_table_list::table, st_table_list::table_name, TL_WRITE, TL_WRITE_CONCURRENT_INSERT, TL_WRITE_DELAYED, TRG_EVENT_INSERT, st_table::triggers, TRUE, st_table_list::updatable, st_copy_info::update_fields, st_copy_info::update_values, st_copy_info::updated, Field::val_int(), st_copy_info::view, st_table_list::view, VIEW_CHECK_ERROR, st_table_list::view_check_option(), VIEW_CHECK_SKIP, write_delayed(), and write_record().
Referenced by mysql_execute_command().
00300 { 00301 int error, res; 00302 /* 00303 log_on is about delayed inserts only. 00304 By default, both logs are enabled (this won't cause problems if the server 00305 runs without --log-update or --log-bin). 00306 */ 00307 bool log_on= ((thd->options & OPTION_BIN_LOG) || 00308 (!(thd->security_ctx->master_access & SUPER_ACL))); 00309 bool transactional_table, joins_freed= FALSE; 00310 bool changed; 00311 uint value_count; 00312 ulong counter = 1; 00313 ulonglong id; 00314 COPY_INFO info; 00315 TABLE *table= 0; 00316 List_iterator_fast<List_item> its(values_list); 00317 List_item *values; 00318 Name_resolution_context *context; 00319 Name_resolution_context_state ctx_state; 00320 #ifndef EMBEDDED_LIBRARY 00321 char *query= thd->query; 00322 #endif 00323 thr_lock_type lock_type = table_list->lock_type; 00324 Item *unused_conds= 0; 00325 DBUG_ENTER("mysql_insert"); 00326 00327 /* 00328 in safe mode or with skip-new change delayed insert to be regular 00329 if we are told to replace duplicates, the insert cannot be concurrent 00330 delayed insert changed to regular in slave thread 00331 */ 00332 #ifdef EMBEDDED_LIBRARY 00333 if (lock_type == TL_WRITE_DELAYED) 00334 lock_type=TL_WRITE; 00335 #else 00336 if ((lock_type == TL_WRITE_DELAYED && 00337 ((specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) || 00338 thd->slave_thread || !thd->variables.max_insert_delayed_threads)) || 00339 (lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE) || 00340 (duplic == DUP_UPDATE)) 00341 lock_type=TL_WRITE; 00342 #endif 00343 table_list->lock_type= lock_type; 00344 00345 #ifndef EMBEDDED_LIBRARY 00346 if (lock_type == TL_WRITE_DELAYED) 00347 { 00348 if (thd->locked_tables) 00349 { 00350 DBUG_ASSERT(table_list->db); /* Must be set in the parser */ 00351 if (find_locked_table(thd, table_list->db, table_list->table_name)) 00352 { 00353 my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0), 00354 table_list->table_name); 00355 DBUG_RETURN(TRUE); 00356 } 00357 } 00358 if ((table= delayed_get_table(thd,table_list)) && !thd->is_fatal_error) 00359 { 00360 /* 00361 Open tables used for sub-selects or in stored functions, will also 00362 cache these functions. 00363 */ 00364 res= open_and_lock_tables(thd, table_list->next_global); 00365 /* 00366 First is not processed by open_and_lock_tables() => we need set 00367 updateability flags "by hands". 00368 */ 00369 if (!table_list->derived && !table_list->view) 00370 table_list->updatable= 1; // usual table 00371 } 00372 else 00373 { 00374 /* Too many delayed insert threads; Use a normal insert */ 00375 table_list->lock_type= lock_type= TL_WRITE; 00376 res= open_and_lock_tables(thd, table_list); 00377 } 00378 } 00379 else 00380 #endif /* EMBEDDED_LIBRARY */ 00381 res= open_and_lock_tables(thd, table_list); 00382 if (res || thd->is_fatal_error) 00383 DBUG_RETURN(TRUE); 00384 00385 thd->proc_info="init"; 00386 thd->used_tables=0; 00387 values= its++; 00388 00389 if (mysql_prepare_insert(thd, table_list, table, fields, values, 00390 update_fields, update_values, duplic, &unused_conds, 00391 FALSE)) 00392 goto abort; 00393 00394 /* mysql_prepare_insert set table_list->table if it was not set */ 00395 table= table_list->table; 00396 00397 context= &thd->lex->select_lex.context; 00398 /* Save the state of the current name resolution context. */ 00399 ctx_state.save_state(context, table_list); 00400 00401 /* 00402 Perform name resolution only in the first table - 'table_list', 00403 which is the table that is inserted into. 00404 */ 00405 table_list->next_local= 0; 00406 context->resolve_in_table_list_only(table_list); 00407 00408 value_count= values->elements; 00409 while ((values= its++)) 00410 { 00411 counter++; 00412 if (values->elements != value_count) 00413 { 00414 my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); 00415 goto abort; 00416 } 00417 if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0)) 00418 goto abort; 00419 } 00420 its.rewind (); 00421 00422 /* Restore the current context. */ 00423 ctx_state.restore_state(context, table_list); 00424 00425 /* 00426 Fill in the given fields and dump it to the table file 00427 */ 00428 info.records= info.deleted= info.copied= info.updated= 0; 00429 info.ignore= ignore; 00430 info.handle_duplicates=duplic; 00431 info.update_fields= &update_fields; 00432 info.update_values= &update_values; 00433 info.view= (table_list->view ? table_list : 0); 00434 00435 /* 00436 Count warnings for all inserts. 00437 For single line insert, generate an error if try to set a NOT NULL field 00438 to NULL. 00439 */ 00440 thd->count_cuted_fields= ((values_list.elements == 1 && 00441 !ignore) ? 00442 CHECK_FIELD_ERROR_FOR_NULL : 00443 CHECK_FIELD_WARN); 00444 thd->cuted_fields = 0L; 00445 table->next_number_field=table->found_next_number_field; 00446 00447 error=0; 00448 thd->proc_info="update"; 00449 if (duplic != DUP_ERROR || ignore) 00450 table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); 00451 if (duplic == DUP_REPLACE && 00452 (!table->triggers || !table->triggers->has_delete_triggers())) 00453 table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); 00454 /* 00455 let's *try* to start bulk inserts. It won't necessary 00456 start them as values_list.elements should be greater than 00457 some - handler dependent - threshold. 00458 We should not start bulk inserts if this statement uses 00459 functions or invokes triggers since they may access 00460 to the same table and therefore should not see its 00461 inconsistent state created by this optimization. 00462 So we call start_bulk_insert to perform nesessary checks on 00463 values_list.elements, and - if nothing else - to initialize 00464 the code to make the call of end_bulk_insert() below safe. 00465 */ 00466 if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode) 00467 table->file->ha_start_bulk_insert(values_list.elements); 00468 00469 thd->no_trans_update= 0; 00470 thd->abort_on_warning= (!ignore && 00471 (thd->variables.sql_mode & 00472 (MODE_STRICT_TRANS_TABLES | 00473 MODE_STRICT_ALL_TABLES))); 00474 00475 if ((fields.elements || !value_count) && 00476 check_that_all_fields_are_given_values(thd, table, table_list)) 00477 { 00478 /* thd->net.report_error is now set, which will abort the next loop */ 00479 error= 1; 00480 } 00481 00482 table->mark_columns_needed_for_insert(); 00483 00484 if (table_list->prepare_where(thd, 0, TRUE) || 00485 table_list->prepare_check_option(thd)) 00486 error= 1; 00487 00488 while ((values= its++)) 00489 { 00490 if (fields.elements || !value_count) 00491 { 00492 restore_record(table,s->default_values); // Get empty record 00493 if (fill_record_n_invoke_before_triggers(thd, fields, *values, 0, 00494 table->triggers, 00495 TRG_EVENT_INSERT)) 00496 { 00497 if (values_list.elements != 1 && !thd->net.report_error) 00498 { 00499 info.records++; 00500 continue; 00501 } 00502 /* 00503 TODO: set thd->abort_on_warning if values_list.elements == 1 00504 and check that all items return warning in case of problem with 00505 storing field. 00506 */ 00507 error=1; 00508 break; 00509 } 00510 } 00511 else 00512 { 00513 if (thd->used_tables) // Column used in values() 00514 restore_record(table,s->default_values); // Get empty record 00515 else 00516 { 00517 /* 00518 Fix delete marker. No need to restore rest of record since it will 00519 be overwritten by fill_record() anyway (and fill_record() does not 00520 use default values in this case). 00521 */ 00522 table->record[0][0]= table->s->default_values[0]; 00523 } 00524 if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0, 00525 table->triggers, 00526 TRG_EVENT_INSERT)) 00527 { 00528 if (values_list.elements != 1 && ! thd->net.report_error) 00529 { 00530 info.records++; 00531 continue; 00532 } 00533 error=1; 00534 break; 00535 } 00536 } 00537 00538 if ((res= table_list->view_check_option(thd, 00539 (values_list.elements == 1 ? 00540 0 : 00541 ignore))) == 00542 VIEW_CHECK_SKIP) 00543 continue; 00544 else if (res == VIEW_CHECK_ERROR) 00545 { 00546 error= 1; 00547 break; 00548 } 00549 #ifndef EMBEDDED_LIBRARY 00550 if (lock_type == TL_WRITE_DELAYED) 00551 { 00552 LEX_STRING const st_query = { query, thd->query_length }; 00553 error=write_delayed(thd, table, duplic, st_query, ignore, log_on); 00554 query=0; 00555 } 00556 else 00557 #endif 00558 error=write_record(thd, table ,&info); 00559 if (error) 00560 break; 00561 thd->row_count++; 00562 } 00563 00564 free_underlaid_joins(thd, &thd->lex->select_lex); 00565 joins_freed= TRUE; 00566 table->file->ha_release_auto_increment(); 00567 00568 /* 00569 Now all rows are inserted. Time to update logs and sends response to 00570 user 00571 */ 00572 #ifndef EMBEDDED_LIBRARY 00573 if (lock_type == TL_WRITE_DELAYED) 00574 { 00575 if (!error) 00576 { 00577 info.copied=values_list.elements; 00578 end_delayed_insert(thd); 00579 } 00580 query_cache_invalidate3(thd, table_list, 1); 00581 } 00582 else 00583 #endif 00584 { 00585 if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error) 00586 { 00587 table->file->print_error(my_errno,MYF(0)); 00588 error=1; 00589 } 00590 transactional_table= table->file->has_transactions(); 00591 00592 if ((changed= (info.copied || info.deleted || info.updated))) 00593 { 00594 /* 00595 Invalidate the table in the query cache if something changed. 00596 For the transactional algorithm to work the invalidation must be 00597 before binlog writing and ha_autocommit_or_rollback 00598 */ 00599 query_cache_invalidate3(thd, table_list, 1); 00600 if (error <= 0 || !transactional_table) 00601 { 00602 if (mysql_bin_log.is_open()) 00603 { 00604 if (error <= 0) 00605 thd->clear_error(); 00606 if (thd->binlog_query(THD::ROW_QUERY_TYPE, 00607 thd->query, thd->query_length, 00608 transactional_table, FALSE) && 00609 transactional_table) 00610 { 00611 error=1; 00612 } 00613 } 00614 if (!transactional_table) 00615 thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; 00616 } 00617 } 00618 if (transactional_table) 00619 error=ha_autocommit_or_rollback(thd,error); 00620 00621 if (thd->lock) 00622 { 00623 mysql_unlock_tables(thd, thd->lock); 00624 /* 00625 Invalidate the table in the query cache if something changed 00626 after unlocking when changes become fisible. 00627 TODO: this is workaround. right way will be move invalidating in 00628 the unlock procedure. 00629 */ 00630 if (lock_type == TL_WRITE_CONCURRENT_INSERT && changed) 00631 { 00632 query_cache_invalidate3(thd, table_list, 1); 00633 } 00634 thd->lock=0; 00635 } 00636 } 00637 thd->proc_info="end"; 00638 /* 00639 We'll report to the client this id: 00640 - if the table contains an autoincrement column and we successfully 00641 inserted an autogenerated value, the autogenerated value. 00642 - if the table contains no autoincrement column and LAST_INSERT_ID(X) was 00643 called, X. 00644 - if the table contains an autoincrement column, and some rows were 00645 inserted, the id of the last "inserted" row (if IGNORE, that value may not 00646 have been really inserted but ignored). 00647 */ 00648 id= (thd->first_successful_insert_id_in_cur_stmt > 0) ? 00649 thd->first_successful_insert_id_in_cur_stmt : 00650 (thd->arg_of_last_insert_id_function ? 00651 thd->first_successful_insert_id_in_prev_stmt : 00652 ((table->next_number_field && info.copied) ? 00653 table->next_number_field->val_int() : 0)); 00654 table->next_number_field=0; 00655 thd->count_cuted_fields= CHECK_FIELD_IGNORE; 00656 if (duplic != DUP_ERROR || ignore) 00657 table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); 00658 if (duplic == DUP_REPLACE && 00659 (!table->triggers || !table->triggers->has_delete_triggers())) 00660 table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); 00661 00662 if (error) 00663 goto abort; 00664 if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) || 00665 !thd->cuted_fields)) 00666 { 00667 thd->row_count_func= info.copied+info.deleted+info.updated; 00668 send_ok(thd, (ulong) thd->row_count_func, id); 00669 } 00670 else 00671 { 00672 char buff[160]; 00673 if (ignore) 00674 sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, 00675 (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 : 00676 (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); 00677 else 00678 sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, 00679 (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); 00680 thd->row_count_func= info.copied+info.deleted+info.updated; 00681 ::send_ok(thd, (ulong) thd->row_count_func, id, buff); 00682 } 00683 thd->abort_on_warning= 0; 00684 DBUG_RETURN(FALSE); 00685 00686 abort: 00687 #ifndef EMBEDDED_LIBRARY 00688 if (lock_type == TL_WRITE_DELAYED) 00689 end_delayed_insert(thd); 00690 #endif 00691 if (table != NULL) 00692 table->file->ha_release_auto_increment(); 00693 if (!joins_freed) 00694 free_underlaid_joins(thd, &thd->lex->select_lex); 00695 thd->abort_on_warning= 0; 00696 DBUG_RETURN(TRUE); 00697 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_insert_select_prepare | ( | THD * | thd | ) |
Definition at line 2273 of file sql_insert.cc.
References st_table_list::belong_to_view, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, FALSE, mysql_prepare_insert(), st_table_list::next_leaf, and TRUE.
02274 { 02275 LEX *lex= thd->lex; 02276 SELECT_LEX *select_lex= &lex->select_lex; 02277 TABLE_LIST *first_select_leaf_table; 02278 DBUG_ENTER("mysql_insert_select_prepare"); 02279 02280 /* 02281 SELECT_LEX do not belong to INSERT statement, so we can't add WHERE 02282 clause if table is VIEW 02283 */ 02284 02285 if (mysql_prepare_insert(thd, lex->query_tables, 02286 lex->query_tables->table, lex->field_list, 0, 02287 lex->update_list, lex->value_list, 02288 lex->duplicates, 02289 &select_lex->where, TRUE)) 02290 DBUG_RETURN(TRUE); 02291 02292 /* 02293 exclude first table from leaf tables list, because it belong to 02294 INSERT 02295 */ 02296 DBUG_ASSERT(select_lex->leaf_tables != 0); 02297 lex->leaf_tables_insert= select_lex->leaf_tables; 02298 /* skip all leaf tables belonged to view where we are insert */ 02299 for (first_select_leaf_table= select_lex->leaf_tables->next_leaf; 02300 first_select_leaf_table && 02301 first_select_leaf_table->belong_to_view && 02302 first_select_leaf_table->belong_to_view == 02303 lex->leaf_tables_insert->belong_to_view; 02304 first_select_leaf_table= first_select_leaf_table->next_leaf) 02305 {} 02306 select_lex->leaf_tables= first_select_leaf_table; 02307 DBUG_RETURN(FALSE); 02308 }
Here is the call graph for this function:

| 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 | |||
| ) |
Definition at line 870 of file sql_insert.cc.
References check_insert_fields(), check_update_fields(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, DUP_REPLACE, DUP_UPDATE, FALSE, Name_resolution_context::first_name_resolution_table, MARK_COLUMNS_READ, mysql_prepare_insert_check_table(), st_table_list::next_local, Name_resolution_context::resolve_in_table_list_only(), Name_resolution_context_state::restore_state(), Name_resolution_context_state::save_next_local, Name_resolution_context_state::save_state(), setup_fields(), Name_resolution_context::table_list, TRUE, unique_table(), update_non_unique_table_error(), and st_table_list::view.
Referenced by mysql_insert(), mysql_insert_select_prepare(), and mysql_test_insert().
00875 { 00876 SELECT_LEX *select_lex= &thd->lex->select_lex; 00877 Name_resolution_context *context= &select_lex->context; 00878 Name_resolution_context_state ctx_state; 00879 bool insert_into_view= (table_list->view != 0); 00880 bool res= 0; 00881 DBUG_ENTER("mysql_prepare_insert"); 00882 DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d", 00883 (ulong)table_list, (ulong)table, 00884 (int)insert_into_view)); 00885 00886 /* 00887 For subqueries in VALUES() we should not see the table in which we are 00888 inserting (for INSERT ... SELECT this is done by changing table_list, 00889 because INSERT ... SELECT share SELECT_LEX it with SELECT. 00890 */ 00891 if (!select_insert) 00892 { 00893 for (SELECT_LEX_UNIT *un= select_lex->first_inner_unit(); 00894 un; 00895 un= un->next_unit()) 00896 { 00897 for (SELECT_LEX *sl= un->first_select(); 00898 sl; 00899 sl= sl->next_select()) 00900 { 00901 sl->context.outer_context= 0; 00902 } 00903 } 00904 } 00905 00906 if (duplic == DUP_UPDATE) 00907 { 00908 /* it should be allocated before Item::fix_fields() */ 00909 if (table_list->set_insert_values(thd->mem_root)) 00910 DBUG_RETURN(TRUE); 00911 } 00912 00913 if (mysql_prepare_insert_check_table(thd, table_list, fields, select_insert)) 00914 DBUG_RETURN(TRUE); 00915 00916 /* Save the state of the current name resolution context. */ 00917 ctx_state.save_state(context, table_list); 00918 00919 /* 00920 Perform name resolution only in the first table - 'table_list', 00921 which is the table that is inserted into. 00922 */ 00923 table_list->next_local= 0; 00924 context->resolve_in_table_list_only(table_list); 00925 00926 /* Prepare the fields in the statement. */ 00927 if (values && 00928 !(res= check_insert_fields(thd, context->table_list, fields, *values, 00929 !insert_into_view) || 00930 setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0)) && 00931 duplic == DUP_UPDATE) 00932 { 00933 select_lex->no_wrap_view_item= TRUE; 00934 res= check_update_fields(thd, context->table_list, update_fields); 00935 select_lex->no_wrap_view_item= FALSE; 00936 /* 00937 When we are not using GROUP BY we can refer to other tables in the 00938 ON DUPLICATE KEY part. 00939 */ 00940 if (select_lex->group_list.elements == 0) 00941 { 00942 context->table_list->next_local= ctx_state.save_next_local; 00943 /* first_name_resolution_table was set by resolve_in_table_list_only() */ 00944 context->first_name_resolution_table-> 00945 next_name_resolution_table= ctx_state.save_next_local; 00946 } 00947 if (!res) 00948 res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0); 00949 } 00950 00951 /* Restore the current context. */ 00952 ctx_state.restore_state(context, table_list); 00953 00954 if (res) 00955 DBUG_RETURN(res); 00956 00957 if (!table) 00958 table= table_list->table; 00959 00960 if (!select_insert) 00961 { 00962 Item *fake_conds= 0; 00963 TABLE_LIST *duplicate; 00964 if ((duplicate= unique_table(thd, table_list, table_list->next_global))) 00965 { 00966 update_non_unique_table_error(table_list, "INSERT", duplicate); 00967 DBUG_RETURN(TRUE); 00968 } 00969 select_lex->fix_prepare_information(thd, &fake_conds); 00970 select_lex->first_execution= 0; 00971 } 00972 if (duplic == DUP_UPDATE || duplic == DUP_REPLACE) 00973 table->prepare_for_position(); 00974 DBUG_RETURN(FALSE); 00975 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool mysql_prepare_insert_check_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| List< Item > & | fields, | |||
| bool | select_insert | |||
| ) | [static] |
Definition at line 806 of file sql_insert.cc.
References DBUG_ENTER, DBUG_RETURN, base_list::elements, ER_VIEW_NO_INSERT_FIELD_LIST, FALSE, insert_view_fields(), my_error(), MYF, SELECT_ACL, st_table_list::select_lex, setup_tables_and_check_access(), LEX_STRING::str, st_table_list::table, TRUE, st_table_list::view, st_table_list::view_db, and st_table_list::view_name.
Referenced by mysql_prepare_insert().
00809 { 00810 bool insert_into_view= (table_list->view != 0); 00811 DBUG_ENTER("mysql_prepare_insert_check_table"); 00812 00813 /* 00814 first table in list is the one we'll INSERT into, requires INSERT_ACL. 00815 all others require SELECT_ACL only. the ACL requirement below is for 00816 new leaves only anyway (view-constituents), so check for SELECT rather 00817 than INSERT. 00818 */ 00819 00820 if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, 00821 &thd->lex->select_lex.top_join_list, 00822 table_list, 00823 &thd->lex->select_lex.leaf_tables, 00824 select_insert, SELECT_ACL)) 00825 DBUG_RETURN(TRUE); 00826 00827 if (insert_into_view && !fields.elements) 00828 { 00829 thd->lex->empty_field_list_on_rset= 1; 00830 if (!table_list->table) 00831 { 00832 my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0), 00833 table_list->view_db.str, table_list->view_name.str); 00834 DBUG_RETURN(TRUE); 00835 } 00836 DBUG_RETURN(insert_view_fields(thd, &fields, table_list)); 00837 } 00838 00839 DBUG_RETURN(FALSE); 00840 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void unlink_blobs | ( | register TABLE * | table | ) | [static] |
Definition at line 2035 of file sql_insert.cc.
References BLOB_FLAG.
Referenced by write_delayed().
02036 { 02037 for (Field **ptr=table->field ; *ptr ; ptr++) 02038 { 02039 if ((*ptr)->flags & BLOB_FLAG) 02040 ((Field_blob *) (*ptr))->clear_temporary(); 02041 } 02042 }
Here is the caller graph for this function:

| static int write_delayed | ( | THD * | thd, | |
| TABLE * | table, | |||
| enum_duplicates | dup, | |||
| LEX_STRING | query, | |||
| bool | ignore, | |||
| bool | log_on | |||
| ) | [static] |
Definition at line 1684 of file sql_insert.cc.
References st_table_share::blob_fields, delayed_insert::cond, delayed_insert::cond_client, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, delayed_queue_size, delayed_rows_in_use, err, delayed_row::first_successful_insert_id_in_prev_stmt, LOCK_delayed_status, memcpy, delayed_insert::mutex, my_free, my_malloc(), my_strndup(), MY_WME, MYF, NULL, pthread_mutex_lock, pthread_mutex_unlock, I_List< T >::push_back(), query, delayed_row::query_start_used, st_table_share::reclength, st_table::record, delayed_row::record, delayed_insert::rows, st_table::s, delayed_insert::stacked_inserts, delayed_row::start_time, delayed_insert::status, delayed_row::stmt_depends_on_first_successful_insert_id_in_prev_stmt, thread_safe_increment, st_table::timestamp_field_type, delayed_row::timestamp_field_type, and unlink_blobs().
Referenced by mysql_insert().
01686 { 01687 delayed_row *row; 01688 delayed_insert *di=thd->di; 01689 DBUG_ENTER("write_delayed"); 01690 DBUG_PRINT("enter", ("query = '%s' length %u", query.str, query.length)); 01691 01692 thd->proc_info="waiting for handler insert"; 01693 pthread_mutex_lock(&di->mutex); 01694 while (di->stacked_inserts >= delayed_queue_size && !thd->killed) 01695 pthread_cond_wait(&di->cond_client,&di->mutex); 01696 thd->proc_info="storing row into queue"; 01697 01698 if (thd->killed) 01699 goto err; 01700 01701 /* 01702 Take a copy of the query string, if there is any. The string will 01703 be free'ed when the row is destroyed. If there is no query string, 01704 we don't do anything special. 01705 */ 01706 01707 if (query.str) 01708 { 01709 char *str; 01710 if (!(str= my_strndup(query.str, query.length, MYF(MY_WME)))) 01711 goto err; 01712 query.str= str; 01713 } 01714 row= new delayed_row(query, duplic, ignore, log_on); 01715 if (row == NULL) 01716 { 01717 my_free(query.str, MYF(MY_WME)); 01718 goto err; 01719 } 01720 01721 if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME)))) 01722 goto err; 01723 memcpy(row->record, table->record[0], table->s->reclength); 01724 row->start_time= thd->start_time; 01725 row->query_start_used= thd->query_start_used; 01726 /* 01727 those are for the binlog: LAST_INSERT_ID() has been evaluated at this 01728 time, so record does not need it, but statement-based binlogging of the 01729 INSERT will need when the row is actually inserted. 01730 As for SET INSERT_ID, DELAYED does not honour it (BUG#20830). 01731 */ 01732 row->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 01733 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt; 01734 row->first_successful_insert_id_in_prev_stmt= 01735 thd->first_successful_insert_id_in_prev_stmt; 01736 row->timestamp_field_type= table->timestamp_field_type; 01737 01738 di->rows.push_back(row); 01739 di->stacked_inserts++; 01740 di->status=1; 01741 if (table->s->blob_fields) 01742 unlink_blobs(table); 01743 pthread_cond_signal(&di->cond); 01744 01745 thread_safe_increment(delayed_rows_in_use,&LOCK_delayed_status); 01746 pthread_mutex_unlock(&di->mutex); 01747 DBUG_RETURN(0); 01748 01749 err: 01750 delete row; 01751 pthread_mutex_unlock(&di->mutex); 01752 DBUG_RETURN(1); 01753 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1016 of file sql_insert.cc.
References handler::adjust_next_insert_id_after_explicit_value(), st_table::column_bitmaps_set(), st_copy_info::copied, current_thd, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, st_copy_info::deleted, handler::dup_ref, DUP_REPLACE, DUP_UPDATE, base_list::elements, err, error, handler::extra(), st_table::file, fill_record_n_invoke_before_triggers(), handler::get_dup_key(), HA_CHECK_DUP, HA_CHECK_DUP_KEY, handler::ha_delete_row(), HA_DUPLICATE_POS, HA_ERR_FOUND_DUPP_KEY, HA_EXTRA_FLUSH_CACHE, HA_READ_KEY_EXACT, handler::ha_table_flags(), handler::ha_update_row(), handler::ha_write_row(), st_copy_info::handle_duplicates, Table_triggers_list::has_delete_triggers(), handler::has_transactions(), st_copy_info::ignore, handler::index_read_idx(), handler::insert_id_for_cur_row, st_table::insert_values, handler::is_fatal_error(), key, key_copy(), st_table::key_info, key_length, st_copy_info::last_errno, last_uniq_key(), MAX_KEY_LENGTH, st_table_share::max_unique_length, my_errno, my_safe_afree, my_safe_alloca, MYF, handler::next_insert_id, st_table::next_number_field, st_table_share::next_number_index, NULL, prev_insert_id(), handler::print_error(), Table_triggers_list::process_triggers(), st_table::read_set, st_table::record, st_copy_info::records, handler::referenced_by_foreign_key(), handler::restore_auto_increment(), restore_record, handler::rnd_pos(), st_table::s, store_record, TIMESTAMP_AUTO_SET_ON_BOTH, st_table::timestamp_field_type, TIMESTAMP_NO_AUTO_SET, TRG_ACTION_AFTER, TRG_ACTION_BEFORE, TRG_EVENT_DELETE, TRG_EVENT_INSERT, TRG_EVENT_UPDATE, st_table::triggers, TRUE, st_copy_info::update_fields, st_copy_info::update_values, st_copy_info::updated, st_table::use_all_columns(), Field::val_int(), st_copy_info::view, VIEW_CHECK_ERROR, st_table_list::view_check_option(), VIEW_CHECK_SKIP, and st_table::write_set.
Referenced by delayed_insert::handle_inserts(), mysql_insert(), read_fixed_length(), and read_sep_field().
01017 { 01018 int error, trg_error= 0; 01019 char *key=0; 01020 MY_BITMAP *save_read_set, *save_write_set; 01021 ulonglong prev_insert_id= table->file->next_insert_id; 01022 ulonglong insert_id_for_cur_row= 0; 01023 DBUG_ENTER("write_record"); 01024 01025 info->records++; 01026 save_read_set= table->read_set; 01027 save_write_set= table->write_set; 01028 01029 if (info->handle_duplicates == DUP_REPLACE || 01030 info->handle_duplicates == DUP_UPDATE) 01031 { 01032 while ((error=table->file->ha_write_row(table->record[0]))) 01033 { 01034 uint key_nr; 01035 /* 01036 If we do more than one iteration of this loop, from the second one the 01037 row will have an explicit value in the autoinc field, which was set at 01038 the first call of handler::update_auto_increment(). So we must save 01039 the autogenerated value to avoid thd->insert_id_for_cur_row to become 01040 0. 01041 */ 01042 if (table->file->insert_id_for_cur_row > 0) 01043 insert_id_for_cur_row= table->file->insert_id_for_cur_row; 01044 else 01045 table->file->insert_id_for_cur_row= insert_id_for_cur_row; 01046 bool is_duplicate_key_error; 01047 if (table->file->is_fatal_error(error, HA_CHECK_DUP)) 01048 goto err; 01049 is_duplicate_key_error= table->file->is_fatal_error(error, 0); 01050 if (!is_duplicate_key_error) 01051 { 01052 /* 01053 We come here when we had an ignorable error which is not a duplicate 01054 key error. In this we ignore error if ignore flag is set, otherwise 01055 report error as usual. We will not do any duplicate key processing. 01056 */ 01057 if (info->ignore) 01058 goto ok_or_after_trg_err; /* Ignoring a not fatal error, return 0 */ 01059 goto err; 01060 } 01061 if ((int) (key_nr = table->file->get_dup_key(error)) < 0) 01062 { 01063 error= HA_ERR_FOUND_DUPP_KEY; /* Database can't find key */ 01064 goto err; 01065 } 01066 /* Read all columns for the row we are going to replace */ 01067 table->use_all_columns(); 01068 /* 01069 Don't allow REPLACE to replace a row when a auto_increment column 01070 was used. This ensures that we don't get a problem when the 01071 whole range of the key has been used. 01072 */ 01073 if (info->handle_duplicates == DUP_REPLACE && 01074 table->next_number_field && 01075 key_nr == table->s->next_number_index && 01076 (insert_id_for_cur_row > 0)) 01077 goto err; 01078 if (table->file->ha_table_flags() & HA_DUPLICATE_POS) 01079 { 01080 if (table->file->rnd_pos(table->record[1],table->file->dup_ref)) 01081 goto err; 01082 } 01083 else 01084 { 01085 if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */ 01086 { 01087 error=my_errno; 01088 goto err; 01089 } 01090 01091 if (!key) 01092 { 01093 if (!(key=(char*) my_safe_alloca(table->s->max_unique_length, 01094 MAX_KEY_LENGTH))) 01095 { 01096 error=ENOMEM; 01097 goto err; 01098 } 01099 } 01100 key_copy((byte*) key,table->record[0],table->key_info+key_nr,0); 01101 if ((error=(table->file->index_read_idx(table->record[1],key_nr, 01102 (byte*) key, 01103 table->key_info[key_nr]. 01104 key_length, 01105 HA_READ_KEY_EXACT)))) 01106 goto err; 01107 } 01108 if (info->handle_duplicates == DUP_UPDATE) 01109 { 01110 int res= 0; 01111 /* 01112 We don't check for other UNIQUE keys - the first row 01113 that matches, is updated. If update causes a conflict again, 01114 an error is returned 01115 */ 01116 DBUG_ASSERT(table->insert_values != NULL); 01117 store_record(table,insert_values); 01118 restore_record(table,record[1]); 01119 DBUG_ASSERT(info->update_fields->elements == 01120 info->update_values->elements); 01121 if (fill_record_n_invoke_before_triggers(thd, *info->update_fields, 01122 *info->update_values, 0, 01123 table->triggers, 01124 TRG_EVENT_UPDATE)) 01125 goto before_trg_err; 01126 01127 /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ 01128 if (info->view && 01129 (res= info->view->view_check_option(current_thd, info->ignore)) == 01130 VIEW_CHECK_SKIP) 01131 goto ok_or_after_trg_err; 01132 if (res == VIEW_CHECK_ERROR) 01133 goto before_trg_err; 01134 01135 if ((error=table->file->ha_update_row(table->record[1], 01136 table->record[0]))) 01137 { 01138 if (info->ignore && 01139 !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) 01140 { 01141 table->file->restore_auto_increment(prev_insert_id); 01142 goto ok_or_after_trg_err; 01143 } 01144 goto err; 01145 } 01146 info->updated++; 01147 /* 01148 If ON DUP KEY UPDATE updates a row instead of inserting one, and 01149 there is an auto_increment column, then SELECT LAST_INSERT_ID() 01150 returns the id of the updated row: 01151 */ 01152 if (table->next_number_field) 01153 { 01154 longlong field_val= table->next_number_field->val_int(); 01155 thd->record_first_successful_insert_id_in_cur_stmt(field_val); 01156 table->file->adjust_next_insert_id_after_explicit_value(field_val); 01157 } 01158 trg_error= (table->triggers && 01159 table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, 01160 TRG_ACTION_AFTER, TRUE)); 01161 info->copied++; 01162 goto ok_or_after_trg_err; 01163 } 01164 else /* DUP_REPLACE */ 01165 { 01166 /* 01167 The manual defines the REPLACE semantics that it is either 01168 an INSERT or DELETE(s) + INSERT; FOREIGN KEY checks in 01169 InnoDB do not function in the defined way if we allow MySQL 01170 to convert the latter operation internally to an UPDATE. 01171 We also should not perform this conversion if we have 01172 timestamp field with ON UPDATE which is different from DEFAULT. 01173 Another case when conversion should not be performed is when 01174 we have ON DELETE trigger on table so user may notice that 01175 we cheat here. Note that it is ok to do such conversion for 01176 tables which have ON UPDATE but have no ON DELETE triggers, 01177 we just should not expose this fact to users by invoking 01178 ON UPDATE triggers. 01179 */ 01180 if (last_uniq_key(table,key_nr) && 01181 !table->file->referenced_by_foreign_key() && 01182 (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET || 01183 table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) && 01184 (!table->triggers || !table->triggers->has_delete_triggers())) 01185 { 01186 if ((error=table->file->ha_update_row(table->record[1], 01187 table->record[0]))) 01188 goto err; 01189 info->deleted++; 01190 thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); 01191 /* 01192 Since we pretend that we have done insert we should call 01193 its after triggers. 01194 */ 01195 goto after_trg_n_copied_inc; 01196 } 01197 else 01198 { 01199 if (table->triggers && 01200 table->triggers->process_triggers(thd, TRG_EVENT_DELETE, 01201 TRG_ACTION_BEFORE, TRUE)) 01202 goto before_trg_err; 01203 if ((error=table->file->ha_delete_row(table->record[1]))) 01204 goto err; 01205 info->deleted++; 01206 if (!table->file->has_transactions()) 01207 thd->no_trans_update= 1; 01208 if (table->triggers && 01209 table->triggers->process_triggers(thd, TRG_EVENT_DELETE, 01210 TRG_ACTION_AFTER, TRUE)) 01211 { 01212 trg_error= 1; 01213 goto ok_or_after_trg_err; 01214 } 01215 /* Let us attempt do write_row() once more */ 01216 } 01217 } 01218 } 01219 thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); 01220 /* 01221 Restore column maps if they where replaced during an duplicate key 01222 problem. 01223 */ 01224 if (table->read_set != save_read_set || 01225 table->write_set != save_write_set) 01226 table->column_bitmaps_set(save_read_set, save_write_set); 01227 } 01228 else if ((error=table->file->ha_write_row(table->record[0]))) 01229 { 01230 if (!info->ignore || 01231 table->file->is_fatal_error(error, HA_CHECK_DUP)) 01232 goto err; 01233 table->file->restore_auto_increment(prev_insert_id); 01234 goto ok_or_after_trg_err; 01235 } 01236 01237 after_trg_n_copied_inc: 01238 info->copied++; 01239 thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); 01240 trg_error= (table->triggers && 01241 table->triggers->process_triggers(thd, TRG_EVENT_INSERT, 01242 TRG_ACTION_AFTER, TRUE)); 01243 01244 ok_or_after_trg_err: 01245 if (key) 01246 my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH); 01247 if (!table->file->has_transactions()) 01248 thd->no_trans_update= 1; 01249 DBUG_RETURN(trg_error); 01250 01251 err: 01252 info->last_errno= error; 01253 /* current_select is NULL if this is a delayed insert */ 01254 if (thd->lex->current_select) 01255 thd->lex->current_select->no_error= 0; // Give error 01256 table->file->print_error(error,MYF(0)); 01257 01258 before_trg_err: 01259 table->file->restore_auto_increment(prev_insert_id); 01260 if (key) 01261 my_safe_afree(key, table->s->max_unique_length, MAX_KEY_LENGTH); 01262 table->column_bitmaps_set(save_read_set, save_write_set); 01263 DBUG_RETURN(1); 01264 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1433 of file sql_insert.cc.
Referenced by find_handler(), handle_delayed_insert(), and kill_delayed_threads().
1.4.7

