00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <drizzled/sql_select.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/probes.h>
00025 #include <drizzled/sql_parse.h>
00026 #include <drizzled/sql_base.h>
00027 #include <drizzled/lock.h>
00028 #include <drizzled/probes.h>
00029 #include <drizzled/optimizer/range.h>
00030 #include <drizzled/records.h>
00031 #include <drizzled/internal/iocache.h>
00032 #include <drizzled/transaction_services.h>
00033 #include <drizzled/filesort.h>
00034 #include <drizzled/sql_lex.h>
00035 #include <drizzled/diagnostics_area.h>
00036 #include <drizzled/statistics_variables.h>
00037 #include <drizzled/session/transactions.h>
00038
00039 namespace drizzled {
00040
00049 bool delete_query(Session *session, TableList *table_list, COND *conds,
00050 SQL_LIST *order, ha_rows limit, uint64_t,
00051 bool reset_auto_increment)
00052 {
00053 int error;
00054 Table *table;
00055 optimizer::SqlSelect *select= NULL;
00056 ReadRecord info;
00057 bool using_limit=limit != HA_POS_ERROR;
00058 ha_rows deleted= 0;
00059 uint32_t usable_index= MAX_KEY;
00060 Select_Lex *select_lex= &session->lex().select_lex;
00061 Session::killed_state_t killed_status= Session::NOT_KILLED;
00062
00063 if (session->openTablesLock(table_list))
00064 {
00065 DRIZZLE_DELETE_DONE(1, 0);
00066 return true;
00067 }
00068
00069 table= table_list->table;
00070 assert(table);
00071
00072 session->set_proc_info("init");
00073 table->map=1;
00074
00075 if (prepare_delete(session, table_list, &conds))
00076 {
00077 DRIZZLE_DELETE_DONE(1, 0);
00078 return true;
00079 }
00080
00081
00082 if (order && order->elements)
00083 {
00084 TableList tables;
00085 List<Item> fields;
00086 List<Item> all_fields;
00087
00088 tables.table = table;
00089 tables.alias = table_list->alias;
00090
00091 select_lex->setup_ref_array(session, order->elements);
00092 if (setup_order(session, select_lex->ref_pointer_array, &tables, fields, all_fields, (Order*) order->first))
00093 {
00094 delete select;
00095 free_underlaid_joins(session, &session->lex().select_lex);
00096 DRIZZLE_DELETE_DONE(1, 0);
00097
00098 return true;
00099 }
00100 }
00101
00102 bool const_cond= not conds || conds->const_item();
00103
00104 select_lex->no_error= session->lex().ignore;
00105
00106 bool const_cond_result= const_cond && (!conds || conds->val_int());
00107 if (session->is_error())
00108 {
00109
00110 return true;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 if (!using_limit && const_cond_result)
00133 {
00134
00135 table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
00136 ha_rows const maybe_deleted= table->cursor->stats.records;
00137 if (!(error=table->cursor->ha_delete_all_rows()))
00138 {
00139 error= -1;
00140 deleted= maybe_deleted;
00141 goto cleanup;
00142 }
00143 if (error != HA_ERR_WRONG_COMMAND)
00144 {
00145 table->print_error(error,MYF(0));
00146 error=0;
00147 goto cleanup;
00148 }
00149
00150 }
00151 if (conds)
00152 {
00153 Item::cond_result result;
00154 conds= remove_eq_conds(session, conds, &result);
00155 if (result == Item::COND_FALSE)
00156 limit= 0;
00157 }
00158
00159
00160 table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
00161
00162 table->covering_keys.reset();
00163 table->quick_keys.reset();
00164 select= optimizer::make_select(table, 0, 0, conds, 0, &error);
00165 if (error)
00166 {
00167 DRIZZLE_DELETE_DONE(1, 0);
00168 return true;
00169 }
00170
00171 if ((select && select->check_quick(session, false, limit)) || !limit)
00172 {
00173 delete select;
00174 free_underlaid_joins(session, select_lex);
00175 session->row_count_func= 0;
00176 if (session->is_error())
00177 return true;
00178 DRIZZLE_DELETE_DONE(0, 0);
00183 session->main_da().reset_diagnostics_area();
00184 session->my_ok((ha_rows) session->rowCount());
00185
00186
00187
00188
00189
00190 return 0;
00191 }
00192
00193
00194 if (table->quick_keys.none())
00195 {
00196 session->server_status|=SERVER_QUERY_NO_INDEX_USED;
00197 }
00198
00199 if (order && order->elements)
00200 {
00201 if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
00202 usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
00203
00204 if (usable_index == MAX_KEY)
00205 {
00206 FileSort filesort(*session);
00207 table->sort.io_cache= new internal::io_cache_st;
00208 uint32_t length= 0;
00209 SortField* sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL);
00210 ha_rows examined_rows;
00211 if ((table->sort.found_records= filesort.run(table, sortorder, length, select, HA_POS_ERROR, 1, examined_rows)) == HA_POS_ERROR)
00212 {
00213 delete select;
00214 free_underlaid_joins(session, &session->lex().select_lex);
00215
00216 DRIZZLE_DELETE_DONE(1, 0);
00217 return true;
00218 }
00219
00220
00221
00222
00223 delete select;
00224 free_underlaid_joins(session, select_lex);
00225 select= 0;
00226 }
00227 }
00228
00229
00230 if (select && select->quick && select->quick->reset())
00231 {
00232 delete select;
00233 free_underlaid_joins(session, select_lex);
00234 DRIZZLE_DELETE_DONE(1, 0);
00235 return true;
00236 }
00237
00238 if (usable_index==MAX_KEY)
00239 {
00240 if ((error= info.init_read_record(session,table,select,1,1)))
00241 {
00242 table->print_error(error, MYF(0));
00243 delete select;
00244 free_underlaid_joins(session, select_lex);
00245 return true;
00246 }
00247 }
00248 else
00249 {
00250 if ((error= info.init_read_record_idx(session, table, 1, usable_index)))
00251 {
00252 table->print_error(error, MYF(0));
00253 delete select;
00254 free_underlaid_joins(session, select_lex);
00255 return true;
00256 }
00257 }
00258
00259 session->set_proc_info("updating");
00260
00261 table->mark_columns_needed_for_delete();
00262
00263 while (!(error=info.read_record(&info)) && !session->getKilled() &&
00264 ! session->is_error())
00265 {
00266
00267 if (!(select && select->skip_record())&& ! session->is_error() )
00268 {
00269 if (!(error= table->cursor->deleteRecord(table->getInsertRecord())))
00270 {
00271 deleted++;
00272 if (!--limit && using_limit)
00273 {
00274 error= -1;
00275 break;
00276 }
00277 }
00278 else
00279 {
00280 table->print_error(error,MYF(0));
00281
00282
00283
00284
00285
00286
00287
00288
00289 error= 1;
00290 break;
00291 }
00292 }
00293 else
00294 table->cursor->unlock_row();
00295 }
00296 killed_status= session->getKilled();
00297 if (killed_status != Session::NOT_KILLED || session->is_error())
00298 error= 1;
00299
00300 session->set_proc_info("end");
00301 info.end_read_record();
00302
00303 cleanup:
00304
00305 if (reset_auto_increment && (error < 0))
00306 {
00307
00308
00309
00310
00311 int error2= table->cursor->ha_reset_auto_increment(0);
00312
00313 if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
00314 {
00315 table->print_error(error2, MYF(0));
00316 error= 1;
00317 }
00318 }
00319
00320 delete select;
00321 bool transactional_table= table->cursor->has_transactions();
00322
00323 if (!transactional_table && deleted > 0)
00324 session->transaction.stmt.markModifiedNonTransData();
00325
00326
00327 if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
00328 {
00329 if (session->transaction.stmt.hasModifiedNonTransData())
00330 session->transaction.all.markModifiedNonTransData();
00331 }
00332 assert(transactional_table || !deleted || session->transaction.stmt.hasModifiedNonTransData());
00333 free_underlaid_joins(session, select_lex);
00334
00335 DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
00336 if (error < 0 || (session->lex().ignore && !session->is_fatal_error))
00337 {
00338 session->row_count_func= deleted;
00343 session->main_da().reset_diagnostics_area();
00344 session->my_ok((ha_rows) session->rowCount());
00345 }
00346 session->status_var.deleted_row_count+= deleted;
00347
00348 return (error >= 0 || session->is_error());
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 int prepare_delete(Session *session, TableList *table_list, Item **conds)
00366 {
00367 Select_Lex *select_lex= &session->lex().select_lex;
00368 session->lex().allow_sum_func= 0;
00369 if (setup_tables_and_check_access(session, &session->lex().select_lex.context, &select_lex->top_join_list,
00370 table_list, &select_lex->leaf_tables, false) ||
00371 session->setup_conds(table_list, conds))
00372 return true;
00373
00374 if (unique_table(table_list, table_list->next_global))
00375 {
00376 my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
00377 return true;
00378 }
00379 List<Item> all_fields;
00380 if (select_lex->inner_refs_list.size() && fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
00381 return true;
00382 return false;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 bool truncate(Session& session, TableList *table_list)
00396 {
00397 uint64_t save_options= session.options;
00398 table_list->lock_type= TL_WRITE;
00399 session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
00400 init_select(&session.lex());
00401 int error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0, HA_POS_ERROR, 0L, true);
00402
00403
00404
00405
00406 error= TransactionServices::autocommitOrRollback(session, error);
00407 session.options= save_options;
00408 return error;
00409 }
00410
00411 }