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

Go to the source code of this file.
Defines | |
| #define | MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size |
Functions | |
| bool | mysql_delete (THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, ha_rows limit, ulonglong options, bool reset_auto_increment) |
| bool | mysql_prepare_delete (THD *thd, TABLE_LIST *table_list, Item **conds) |
| int | refpos_order_cmp (void *arg, const void *a, const void *b) |
| bool | mysql_multi_delete_prepare (THD *thd) |
| bool | mysql_truncate (THD *thd, TABLE_LIST *table_list, bool dont_send_ok) |
| #define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size |
Definition at line 415 of file sql_delete.cc.
| bool mysql_delete | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| COND * | conds, | |||
| SQL_LIST * | order, | |||
| ha_rows | limit, | |||
| ulonglong | options, | |||
| bool | reset_auto_increment | |||
| ) |
Definition at line 31 of file sql_delete.cc.
References st_table_list::alias, st_table::alias, bzero, SQL_SELECT::check_quick(), cleanup(), Bitmap< 64 >::clear_all(), Item::COND_FALSE, Item::const_item(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, handler::delete_all_rows(), handler::end_bulk_delete(), end_read_record(), ER, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER_VIEW_DELETE_MERGE_VIEW, error, handler::extra(), FALSE, st_table::file, filesort(), st_filesort_info::found_records, free_underlaid_joins(), get_index_for_order(), ha_autocommit_or_rollback(), handler::ha_delete_row(), HA_ERR_WRONG_COMMAND, HA_EXTRA_NORMAL, HA_EXTRA_QUICK, HA_POS_ERROR, HA_STATUS_NO_LOCK, HA_STATUS_VARIABLE, Table_triggers_list::has_delete_triggers(), handler::has_transactions(), handler::info(), info, init_ftfuncs(), init_read_record(), init_read_record_idx(), st_filesort_info::io_cache, Bitmap< 64 >::is_clear_all(), MYSQL_LOG::is_open(), make_select(), make_unireg_sortorder(), st_table::map, st_table::mark_columns_needed_for_delete(), MAX_KEY, my_error(), MY_FAE, my_malloc(), my_message(), MY_ZEROFILL, MYF, mysql_bin_log, mysql_prepare_delete(), mysql_unlock_tables(), open_and_lock_tables(), OPTION_QUICK, OPTION_SAFE_UPDATES, OPTION_STATUS_NO_TRANS_UPDATE, order, handler::print_error(), Table_triggers_list::process_triggers(), SQL_SELECT::quick, st_table::quick_keys, st_table::record, ha_statistics::records, remove_eq_conds(), QUICK_SELECT_I::reset(), handler::reset_auto_increment(), send_ok(), SERVER_QUERY_NO_INDEX_USED, setup_order(), SQL_SELECT::skip_record(), st_table::sort, SPECIAL_NO_NEW_FUNC, SPECIAL_SAFE_MODE, specialflag, handler::start_bulk_delete(), handler::stats, LEX_STRING::str, st_table_list::table, test, TRG_ACTION_AFTER, TRG_ACTION_BEFORE, TRG_EVENT_DELETE, st_table::triggers, TRUE, handler::unlock_row(), st_table::used_keys, Item::val_int(), st_table_list::view_db, and st_table_list::view_name.
Referenced by mysql_execute_command(), and mysql_truncate().
00034 { 00035 bool will_batch; 00036 int error, loc_error; 00037 TABLE *table; 00038 SQL_SELECT *select=0; 00039 READ_RECORD info; 00040 bool using_limit=limit != HA_POS_ERROR; 00041 bool transactional_table, safe_update, const_cond; 00042 ha_rows deleted= 0; 00043 uint usable_index= MAX_KEY; 00044 SELECT_LEX *select_lex= &thd->lex->select_lex; 00045 DBUG_ENTER("mysql_delete"); 00046 00047 if (open_and_lock_tables(thd, table_list)) 00048 DBUG_RETURN(TRUE); 00049 if (!(table= table_list->table)) 00050 { 00051 my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), 00052 table_list->view_db.str, table_list->view_name.str); 00053 DBUG_RETURN(TRUE); 00054 } 00055 thd->proc_info="init"; 00056 table->map=1; 00057 00058 if (mysql_prepare_delete(thd, table_list, &conds)) 00059 DBUG_RETURN(TRUE); 00060 00061 const_cond= (!conds || conds->const_item()); 00062 safe_update=test(thd->options & OPTION_SAFE_UPDATES); 00063 if (safe_update && const_cond) 00064 { 00065 my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, 00066 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); 00067 DBUG_RETURN(TRUE); 00068 } 00069 00070 select_lex->no_error= thd->lex->ignore; 00071 00072 /* 00073 Test if the user wants to delete all rows and deletion doesn't have 00074 any side-effects (because of triggers), so we can use optimized 00075 handler::delete_all_rows() method. 00076 00077 If row-based replication is used, we also delete the table row by 00078 row. 00079 */ 00080 if (!using_limit && const_cond && (!conds || conds->val_int()) && 00081 !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && 00082 !(table->triggers && table->triggers->has_delete_triggers()) && 00083 !thd->current_stmt_binlog_row_based) 00084 { 00085 /* Update the table->file->stats.records number */ 00086 table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); 00087 ha_rows const maybe_deleted= table->file->stats.records; 00088 DBUG_PRINT("debug", ("Trying to use delete_all_rows()")); 00089 if (!(error=table->file->delete_all_rows())) 00090 { 00091 error= -1; // ok 00092 deleted= maybe_deleted; 00093 goto cleanup; 00094 } 00095 if (error != HA_ERR_WRONG_COMMAND) 00096 { 00097 table->file->print_error(error,MYF(0)); 00098 error=0; 00099 goto cleanup; 00100 } 00101 /* Handler didn't support fast delete; Delete rows one by one */ 00102 } 00103 if (conds) 00104 { 00105 Item::cond_result result; 00106 conds= remove_eq_conds(thd, conds, &result); 00107 if (result == Item::COND_FALSE) // Impossible where 00108 limit= 0; 00109 } 00110 00111 #ifdef WITH_PARTITION_STORAGE_ENGINE 00112 if (prune_partitions(thd, table, conds)) 00113 { 00114 free_underlaid_joins(thd, select_lex); 00115 thd->row_count_func= 0; 00116 send_ok(thd); // No matching records 00117 DBUG_RETURN(0); 00118 } 00119 #endif 00120 /* Update the table->file->stats.records number */ 00121 table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); 00122 00123 table->used_keys.clear_all(); 00124 table->quick_keys.clear_all(); // Can't use 'only index' 00125 select=make_select(table, 0, 0, conds, 0, &error); 00126 if (error) 00127 DBUG_RETURN(TRUE); 00128 if ((select && select->check_quick(thd, safe_update, limit)) || !limit) 00129 { 00130 delete select; 00131 free_underlaid_joins(thd, select_lex); 00132 thd->row_count_func= 0; 00133 send_ok(thd,0L); 00134 /* 00135 We don't need to call reset_auto_increment in this case, because 00136 mysql_truncate always gives a NULL conds argument, hence we never 00137 get here. 00138 */ 00139 DBUG_RETURN(0); // Nothing to delete 00140 } 00141 00142 /* If running in safe sql mode, don't allow updates without keys */ 00143 if (table->quick_keys.is_clear_all()) 00144 { 00145 thd->server_status|=SERVER_QUERY_NO_INDEX_USED; 00146 if (safe_update && !using_limit) 00147 { 00148 delete select; 00149 free_underlaid_joins(thd, select_lex); 00150 my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, 00151 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); 00152 DBUG_RETURN(TRUE); 00153 } 00154 } 00155 if (options & OPTION_QUICK) 00156 (void) table->file->extra(HA_EXTRA_QUICK); 00157 00158 if (order && order->elements) 00159 { 00160 uint length; 00161 SORT_FIELD *sortorder; 00162 TABLE_LIST tables; 00163 List<Item> fields; 00164 List<Item> all_fields; 00165 ha_rows examined_rows; 00166 00167 bzero((char*) &tables,sizeof(tables)); 00168 tables.table = table; 00169 tables.alias = table_list->alias; 00170 00171 if (select_lex->setup_ref_array(thd, order->elements) || 00172 setup_order(thd, select_lex->ref_pointer_array, &tables, 00173 fields, all_fields, (ORDER*) order->first)) 00174 { 00175 delete select; 00176 free_underlaid_joins(thd, &thd->lex->select_lex); 00177 DBUG_RETURN(TRUE); 00178 } 00179 00180 if (!select && limit != HA_POS_ERROR) 00181 usable_index= get_index_for_order(table, (ORDER*)(order->first), limit); 00182 00183 if (usable_index == MAX_KEY) 00184 { 00185 table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE), 00186 MYF(MY_FAE | MY_ZEROFILL)); 00187 00188 if (!(sortorder= make_unireg_sortorder((ORDER*) order->first, 00189 &length)) || 00190 (table->sort.found_records = filesort(thd, table, sortorder, length, 00191 select, HA_POS_ERROR, 1, 00192 &examined_rows)) 00193 == HA_POS_ERROR) 00194 { 00195 delete select; 00196 free_underlaid_joins(thd, &thd->lex->select_lex); 00197 DBUG_RETURN(TRUE); 00198 } 00199 /* 00200 Filesort has already found and selected the rows we want to delete, 00201 so we don't need the where clause 00202 */ 00203 delete select; 00204 free_underlaid_joins(thd, select_lex); 00205 select= 0; 00206 } 00207 } 00208 00209 /* If quick select is used, initialize it before retrieving rows. */ 00210 if (select && select->quick && select->quick->reset()) 00211 { 00212 delete select; 00213 free_underlaid_joins(thd, select_lex); 00214 DBUG_RETURN(TRUE); 00215 } 00216 if (usable_index==MAX_KEY) 00217 init_read_record(&info,thd,table,select,1,1); 00218 else 00219 init_read_record_idx(&info, thd, table, 1, usable_index); 00220 00221 init_ftfuncs(thd, select_lex, 1); 00222 thd->proc_info="updating"; 00223 will_batch= !table->file->start_bulk_delete(); 00224 00225 00226 table->mark_columns_needed_for_delete(); 00227 00228 while (!(error=info.read_record(&info)) && !thd->killed && 00229 !thd->net.report_error) 00230 { 00231 // thd->net.report_error is tested to disallow delete row on error 00232 if (!(select && select->skip_record())&& !thd->net.report_error ) 00233 { 00234 00235 if (table->triggers && 00236 table->triggers->process_triggers(thd, TRG_EVENT_DELETE, 00237 TRG_ACTION_BEFORE, FALSE)) 00238 { 00239 error= 1; 00240 break; 00241 } 00242 00243 if (!(error= table->file->ha_delete_row(table->record[0]))) 00244 { 00245 deleted++; 00246 if (table->triggers && 00247 table->triggers->process_triggers(thd, TRG_EVENT_DELETE, 00248 TRG_ACTION_AFTER, FALSE)) 00249 { 00250 error= 1; 00251 break; 00252 } 00253 if (!--limit && using_limit) 00254 { 00255 error= -1; 00256 break; 00257 } 00258 } 00259 else 00260 { 00261 table->file->print_error(error,MYF(0)); 00262 /* 00263 In < 4.0.14 we set the error number to 0 here, but that 00264 was not sensible, because then MySQL would not roll back the 00265 failed DELETE, and also wrote it to the binlog. For MyISAM 00266 tables a DELETE probably never should fail (?), but for 00267 InnoDB it can fail in a FOREIGN KEY error or an 00268 out-of-tablespace error. 00269 */ 00270 error= 1; 00271 break; 00272 } 00273 } 00274 else 00275 table->file->unlock_row(); // Row failed selection, release lock on it 00276 } 00277 if (thd->killed && !error) 00278 error= 1; // Aborted 00279 if (will_batch && (loc_error= table->file->end_bulk_delete())) 00280 { 00281 if (error != 1) 00282 table->file->print_error(loc_error,MYF(0)); 00283 error=1; 00284 } 00285 thd->proc_info= "end"; 00286 end_read_record(&info); 00287 if (options & OPTION_QUICK) 00288 (void) table->file->extra(HA_EXTRA_NORMAL); 00289 00290 if (reset_auto_increment && (error < 0)) 00291 { 00292 /* 00293 We're really doing a truncate and need to reset the table's 00294 auto-increment counter. 00295 */ 00296 int error2= table->file->reset_auto_increment(0); 00297 00298 if (error2 && (error2 != HA_ERR_WRONG_COMMAND)) 00299 { 00300 table->file->print_error(error2, MYF(0)); 00301 error= 1; 00302 } 00303 } 00304 00305 cleanup: 00306 /* 00307 Invalidate the table in the query cache if something changed. This must 00308 be before binlog writing and ha_autocommit_... 00309 */ 00310 if (deleted) 00311 { 00312 query_cache_invalidate3(thd, table_list, 1); 00313 } 00314 00315 delete select; 00316 transactional_table= table->file->has_transactions(); 00317 00318 /* See similar binlogging code in sql_update.cc, for comments */ 00319 if ((error < 0) || (deleted && !transactional_table)) 00320 { 00321 if (mysql_bin_log.is_open()) 00322 { 00323 if (error < 0) 00324 thd->clear_error(); 00325 00326 /* 00327 [binlog]: If 'handler::delete_all_rows()' was called and the 00328 storage engine does not inject the rows itself, we replicate 00329 statement-based; otherwise, 'ha_delete_row()' was used to 00330 delete specific rows which we might log row-based. 00331 */ 00332 int log_result= thd->binlog_query(THD::ROW_QUERY_TYPE, 00333 thd->query, thd->query_length, 00334 transactional_table, FALSE); 00335 00336 if (log_result && transactional_table) 00337 { 00338 error=1; 00339 } 00340 } 00341 if (!transactional_table) 00342 thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; 00343 } 00344 free_underlaid_joins(thd, select_lex); 00345 if (transactional_table) 00346 { 00347 if (ha_autocommit_or_rollback(thd,error >= 0)) 00348 error=1; 00349 } 00350 00351 if (thd->lock) 00352 { 00353 mysql_unlock_tables(thd, thd->lock); 00354 thd->lock=0; 00355 } 00356 if (error < 0) 00357 { 00358 thd->row_count_func= deleted; 00359 send_ok(thd,deleted); 00360 DBUG_PRINT("info",("%d records deleted",deleted)); 00361 } 00362 DBUG_RETURN(error >= 0 || thd->net.report_error); 00363 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_multi_delete_prepare | ( | THD * | thd | ) |
Definition at line 435 of file sql_delete.cc.
References check_key_in_view(), st_table_list::correspondent_table, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, DELETE_ACL, ER_NON_UPDATABLE_TABLE, ER_VIEW_DELETE_MERGE_VIEW, FALSE, st_table_list::merge_underlying_list, my_error(), MYF, st_table_list::next_local, setup_tables_and_check_access(), LEX_STRING::str, st_table_list::table, st_table_list::table_name, TRUE, st_table_list::updatable, st_table_list::view, st_table_list::view_db, and st_table_list::view_name.
00436 { 00437 LEX *lex= thd->lex; 00438 TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first; 00439 TABLE_LIST *target_tbl; 00440 DBUG_ENTER("mysql_multi_delete_prepare"); 00441 00442 /* 00443 setup_tables() need for VIEWs. JOIN::prepare() will not do it second 00444 time. 00445 00446 lex->query_tables also point on local list of DELETE SELECT_LEX 00447 */ 00448 if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, 00449 &thd->lex->select_lex.top_join_list, 00450 lex->query_tables, 00451 &lex->select_lex.leaf_tables, FALSE, 00452 DELETE_ACL)) 00453 DBUG_RETURN(TRUE); 00454 00455 00456 /* 00457 Multi-delete can't be constructed over-union => we always have 00458 single SELECT on top and have to check underlying SELECTs of it 00459 */ 00460 lex->select_lex.exclude_from_table_unique_test= TRUE; 00461 /* Fix tables-to-be-deleted-from list to point at opened tables */ 00462 for (target_tbl= (TABLE_LIST*) aux_tables; 00463 target_tbl; 00464 target_tbl= target_tbl->next_local) 00465 { 00466 if (!(target_tbl->table= target_tbl->correspondent_table->table)) 00467 { 00468 DBUG_ASSERT(target_tbl->correspondent_table->view && 00469 target_tbl->correspondent_table->merge_underlying_list && 00470 target_tbl->correspondent_table->merge_underlying_list-> 00471 next_local); 00472 my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), 00473 target_tbl->correspondent_table->view_db.str, 00474 target_tbl->correspondent_table->view_name.str); 00475 DBUG_RETURN(TRUE); 00476 } 00477 00478 if (!target_tbl->correspondent_table->updatable || 00479 check_key_in_view(thd, target_tbl->correspondent_table)) 00480 { 00481 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), 00482 target_tbl->table_name, "DELETE"); 00483 DBUG_RETURN(TRUE); 00484 } 00485 /* 00486 Check that table from which we delete is not used somewhere 00487 inside subqueries/view. 00488 */ 00489 { 00490 TABLE_LIST *duplicate; 00491 if ((duplicate= unique_table(thd, target_tbl->correspondent_table, 00492 lex->query_tables))) 00493 { 00494 update_non_unique_table_error(target_tbl->correspondent_table, 00495 "DELETE", duplicate); 00496 DBUG_RETURN(TRUE); 00497 } 00498 } 00499 } 00500 DBUG_RETURN(FALSE); 00501 }
Here is the call graph for this function:

| bool mysql_prepare_delete | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| Item ** | conds | |||
| ) |
Definition at line 379 of file sql_delete.cc.
References st_table_list::alias, check_key_in_view(), DBUG_ENTER, DBUG_RETURN, DELETE_ACL, ER_NON_UPDATABLE_TABLE, FALSE, my_error(), MYF, st_table_list::next_global, setup_conds(), setup_ftfuncs(), setup_tables_and_check_access(), TRUE, unique_table(), st_table_list::updatable, and update_non_unique_table_error().
Referenced by mysql_delete(), and mysql_test_delete().
00380 { 00381 SELECT_LEX *select_lex= &thd->lex->select_lex; 00382 DBUG_ENTER("mysql_prepare_delete"); 00383 00384 thd->lex->allow_sum_func= 0; 00385 if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, 00386 &thd->lex->select_lex.top_join_list, 00387 table_list, 00388 &select_lex->leaf_tables, FALSE, 00389 DELETE_ACL) || 00390 setup_conds(thd, table_list, select_lex->leaf_tables, conds) || 00391 setup_ftfuncs(select_lex)) 00392 DBUG_RETURN(TRUE); 00393 if (!table_list->updatable || check_key_in_view(thd, table_list)) 00394 { 00395 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); 00396 DBUG_RETURN(TRUE); 00397 } 00398 { 00399 TABLE_LIST *duplicate; 00400 if ((duplicate= unique_table(thd, table_list, table_list->next_global))) 00401 { 00402 update_non_unique_table_error(table_list, "DELETE", duplicate); 00403 DBUG_RETURN(TRUE); 00404 } 00405 } 00406 select_lex->fix_prepare_information(thd, conds); 00407 DBUG_RETURN(FALSE); 00408 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_truncate | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| bool | dont_send_ok | |||
| ) |
Definition at line 859 of file sql_delete.cc.
References build_table_filename(), bzero, LOGGER::close_log_table(), close_temporary_table(), st_table_list::db, st_table_share::db, st_table_share::db_type, DB_TYPE_UNKNOWN, DBUG_ENTER, DBUG_RETURN, ER_NO_SUCH_TABLE, error, FALSE, st_table::file, find_temporary_table(), FN_REFLEN, free_table_share(), ha_check_storage_engine_flag(), ha_create_table(), ha_enable_transaction(), HA_POS_ERROR, ha_resolve_by_legacy_type(), HA_STATUS_AUTO, HA_STATUS_NO_LOCK, HTON_CAN_RECREATE, handler::info(), MYSQL_LOG::is_open(), LL, LOGGER::lock(), lock_and_wait_for_table_name(), LOCK_open, st_table_list::lock_type, logger, my_error(), my_free, my_strcasecmp, MYF, mysql_bin_log, mysql_delete(), mysql_frm_type(), mysql_init_select(), st_table_share::normalized_path, open_temporary_table(), opt_log, opt_slow_log, OPTION_BEGIN, OPTION_NOT_AUTOCOMMIT, st_table_share::path, path, pthread_mutex_lock, pthread_mutex_unlock, QUERY_LOG_GENERAL, QUERY_LOG_SLOW, reg_ext, reg_ext_length, LOGGER::reopen_log_table(), rm_temporary_table(), st_table::s, send_ok(), LEX_STRING::str, system_charset_info, st_table_list::table_name, st_table_share::table_name, TL_WRITE, TRUE, LOGGER::unlock(), unlock_table_name(), and VOID.
Referenced by mysql_execute_command(), prepare_for_repair(), and prepare_for_restore().
00860 { 00861 HA_CREATE_INFO create_info; 00862 char path[FN_REFLEN]; 00863 TABLE *table; 00864 bool error; 00865 uint closed_log_tables= 0, lock_logger= 0; 00866 uint path_length; 00867 DBUG_ENTER("mysql_truncate"); 00868 00869 bzero((char*) &create_info,sizeof(create_info)); 00870 /* If it is a temporary table, close and regenerate it */ 00871 if (!dont_send_ok && (table= find_temporary_table(thd, table_list))) 00872 { 00873 handlerton *table_type= table->s->db_type; 00874 TABLE_SHARE *share= table->s; 00875 if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE)) 00876 goto trunc_by_del; 00877 00878 table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); 00879 00880 close_temporary_table(thd, table, 0, 0); // Don't free share 00881 ha_create_table(thd, share->normalized_path.str, 00882 share->db.str, share->table_name.str, &create_info, 1); 00883 // We don't need to call invalidate() because this table is not in cache 00884 if ((error= (int) !(open_temporary_table(thd, share->path.str, 00885 share->db.str, 00886 share->table_name.str, 1)))) 00887 (void) rm_temporary_table(table_type, path); 00888 free_table_share(share); 00889 my_free((char*) table,MYF(0)); 00890 /* 00891 If we return here we will not have logged the truncation to the bin log 00892 and we will not send_ok() to the client. 00893 */ 00894 goto end; 00895 } 00896 00897 path_length= build_table_filename(path, sizeof(path), table_list->db, 00898 table_list->table_name, reg_ext, 0); 00899 00900 if (!dont_send_ok) 00901 { 00902 enum legacy_db_type table_type; 00903 mysql_frm_type(thd, path, &table_type); 00904 if (table_type == DB_TYPE_UNKNOWN) 00905 { 00906 my_error(ER_NO_SUCH_TABLE, MYF(0), 00907 table_list->db, table_list->table_name); 00908 DBUG_RETURN(TRUE); 00909 } 00910 if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, table_type), 00911 HTON_CAN_RECREATE)) 00912 goto trunc_by_del; 00913 00914 if (lock_and_wait_for_table_name(thd, table_list)) 00915 DBUG_RETURN(TRUE); 00916 } 00917 00918 /* close log tables in use */ 00919 if (!my_strcasecmp(system_charset_info, table_list->db, "mysql")) 00920 { 00921 if (opt_log && 00922 !my_strcasecmp(system_charset_info, table_list->table_name, 00923 "general_log")) 00924 { 00925 lock_logger= 1; 00926 logger.lock(); 00927 logger.close_log_table(QUERY_LOG_GENERAL, FALSE); 00928 closed_log_tables= closed_log_tables | QUERY_LOG_GENERAL; 00929 } 00930 else 00931 if (opt_slow_log && 00932 !my_strcasecmp(system_charset_info, table_list->table_name, 00933 "slow_log")) 00934 { 00935 lock_logger= 1; 00936 logger.lock(); 00937 logger.close_log_table(QUERY_LOG_SLOW, FALSE); 00938 closed_log_tables= closed_log_tables | QUERY_LOG_SLOW; 00939 } 00940 } 00941 00942 // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this 00943 // crashes, replacement works. *(path + path_length - reg_ext_length)= 00944 // '\0'; 00945 path[path_length - reg_ext_length] = 0; 00946 VOID(pthread_mutex_lock(&LOCK_open)); 00947 error= ha_create_table(thd, path, table_list->db, table_list->table_name, 00948 &create_info, 1); 00949 VOID(pthread_mutex_unlock(&LOCK_open)); 00950 query_cache_invalidate3(thd, table_list, 0); 00951 00952 end: 00953 if (!dont_send_ok) 00954 { 00955 if (!error) 00956 { 00957 if (mysql_bin_log.is_open()) 00958 { 00959 /* 00960 TRUNCATE must always be statement-based binlogged (not row-based) so 00961 we don't test current_stmt_binlog_row_based. 00962 */ 00963 thd->clear_error(); 00964 thd->binlog_query(THD::STMT_QUERY_TYPE, 00965 thd->query, thd->query_length, FALSE, FALSE); 00966 } 00967 send_ok(thd); // This should return record count 00968 } 00969 VOID(pthread_mutex_lock(&LOCK_open)); 00970 unlock_table_name(thd, table_list); 00971 VOID(pthread_mutex_unlock(&LOCK_open)); 00972 00973 if (opt_slow_log && (closed_log_tables & QUERY_LOG_SLOW)) 00974 logger.reopen_log_table(QUERY_LOG_SLOW); 00975 00976 if (opt_log && (closed_log_tables & QUERY_LOG_GENERAL)) 00977 logger.reopen_log_table(QUERY_LOG_GENERAL); 00978 if (lock_logger) 00979 logger.unlock(); 00980 } 00981 else if (error) 00982 { 00983 VOID(pthread_mutex_lock(&LOCK_open)); 00984 unlock_table_name(thd, table_list); 00985 VOID(pthread_mutex_unlock(&LOCK_open)); 00986 } 00987 DBUG_RETURN(error); 00988 00989 trunc_by_del: 00990 /* Probably InnoDB table */ 00991 ulong save_options= thd->options; 00992 table_list->lock_type= TL_WRITE; 00993 thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT); 00994 ha_enable_transaction(thd, FALSE); 00995 mysql_init_select(thd->lex); 00996 bool save_binlog_row_based= thd->current_stmt_binlog_row_based; 00997 thd->clear_current_stmt_binlog_row_based(); 00998 error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0, 00999 HA_POS_ERROR, LL(0), TRUE); 01000 ha_enable_transaction(thd, TRUE); 01001 thd->options= save_options; 01002 thd->current_stmt_binlog_row_based= save_binlog_row_based; 01003 DBUG_RETURN(error); 01004 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int refpos_order_cmp | ( | void * | arg, | |
| const void * | a, | |||
| const void * | b | |||
| ) |
Definition at line 417 of file sql_delete.cc.
References handler::cmp_ref().
Referenced by QUICK_INDEX_MERGE_SELECT::read_keys_and_merge().
00418 { 00419 handler *file= (handler*)arg; 00420 return file->cmp_ref((const byte*)a, (const byte*)b); 00421 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

