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
00036 namespace drizzled
00037 {
00038
00047 bool delete_query(Session *session, TableList *table_list, COND *conds,
00048 SQL_LIST *order, ha_rows limit, uint64_t,
00049 bool reset_auto_increment)
00050 {
00051 int error;
00052 Table *table;
00053 optimizer::SqlSelect *select= NULL;
00054 ReadRecord info;
00055 bool using_limit=limit != HA_POS_ERROR;
00056 bool transactional_table, const_cond;
00057 bool const_cond_result;
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 if (select_lex->setup_ref_array(session, order->elements) ||
00092 setup_order(session, select_lex->ref_pointer_array, &tables,
00093 fields, all_fields, (Order*) order->first))
00094 {
00095 delete select;
00096 free_underlaid_joins(session, &session->lex().select_lex);
00097 DRIZZLE_DELETE_DONE(1, 0);
00098
00099 return true;
00100 }
00101 }
00102
00103 const_cond= (!conds || conds->const_item());
00104
00105 select_lex->no_error= session->lex().ignore;
00106
00107 const_cond_result= const_cond && (!conds || conds->val_int());
00108 if (session->is_error())
00109 {
00110
00111 return(true);
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 if (!using_limit && const_cond_result)
00134 {
00135
00136 table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
00137 ha_rows const maybe_deleted= table->cursor->stats.records;
00138 if (!(error=table->cursor->ha_delete_all_rows()))
00139 {
00140 error= -1;
00141 deleted= maybe_deleted;
00142 goto cleanup;
00143 }
00144 if (error != HA_ERR_WRONG_COMMAND)
00145 {
00146 table->print_error(error,MYF(0));
00147 error=0;
00148 goto cleanup;
00149 }
00150
00151 }
00152 if (conds)
00153 {
00154 Item::cond_result result;
00155 conds= remove_eq_conds(session, conds, &result);
00156 if (result == Item::COND_FALSE)
00157 limit= 0;
00158 }
00159
00160
00161 table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
00162
00163 table->covering_keys.reset();
00164 table->quick_keys.reset();
00165 select= optimizer::make_select(table, 0, 0, conds, 0, &error);
00166 if (error)
00167 {
00168 DRIZZLE_DELETE_DONE(1, 0);
00169 return true;
00170 }
00171
00172 if ((select && select->check_quick(session, false, limit)) || !limit)
00173 {
00174 delete select;
00175 free_underlaid_joins(session, select_lex);
00176 session->row_count_func= 0;
00177 if (session->is_error())
00178 return true;
00179 DRIZZLE_DELETE_DONE(0, 0);
00184 session->main_da.reset_diagnostics_area();
00185 session->my_ok((ha_rows) session->rowCount());
00186
00187
00188
00189
00190
00191 return 0;
00192 }
00193
00194
00195 if (table->quick_keys.none())
00196 {
00197 session->server_status|=SERVER_QUERY_NO_INDEX_USED;
00198 }
00199
00200 if (order && order->elements)
00201 {
00202 uint32_t length= 0;
00203 SortField *sortorder;
00204 ha_rows examined_rows;
00205
00206 if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
00207 usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
00208
00209 if (usable_index == MAX_KEY)
00210 {
00211 FileSort filesort(*session);
00212 table->sort.io_cache= new internal::IO_CACHE;
00213
00214
00215 if (not (sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL)) ||
00216 (table->sort.found_records = filesort.run(table, sortorder, length,
00217 select, HA_POS_ERROR, 1,
00218 examined_rows)) == HA_POS_ERROR)
00219 {
00220 delete select;
00221 free_underlaid_joins(session, &session->lex().select_lex);
00222
00223 DRIZZLE_DELETE_DONE(1, 0);
00224 return true;
00225 }
00226
00227
00228
00229
00230 delete select;
00231 free_underlaid_joins(session, select_lex);
00232 select= 0;
00233 }
00234 }
00235
00236
00237 if (select && select->quick && select->quick->reset())
00238 {
00239 delete select;
00240 free_underlaid_joins(session, select_lex);
00241 DRIZZLE_DELETE_DONE(1, 0);
00242 return true;
00243 }
00244
00245 if (usable_index==MAX_KEY)
00246 {
00247 if ((error= info.init_read_record(session,table,select,1,1)))
00248 {
00249 table->print_error(error, MYF(0));
00250 delete select;
00251 free_underlaid_joins(session, select_lex);
00252 return true;
00253 }
00254 }
00255 else
00256 {
00257 if ((error= info.init_read_record_idx(session, table, 1, usable_index)))
00258 {
00259 table->print_error(error, MYF(0));
00260 delete select;
00261 free_underlaid_joins(session, select_lex);
00262 return true;
00263 }
00264 }
00265
00266 session->set_proc_info("updating");
00267
00268 table->mark_columns_needed_for_delete();
00269
00270 while (!(error=info.read_record(&info)) && !session->getKilled() &&
00271 ! session->is_error())
00272 {
00273
00274 if (!(select && select->skip_record())&& ! session->is_error() )
00275 {
00276 if (!(error= table->cursor->deleteRecord(table->getInsertRecord())))
00277 {
00278 deleted++;
00279 if (!--limit && using_limit)
00280 {
00281 error= -1;
00282 break;
00283 }
00284 }
00285 else
00286 {
00287 table->print_error(error,MYF(0));
00288
00289
00290
00291
00292
00293
00294
00295
00296 error= 1;
00297 break;
00298 }
00299 }
00300 else
00301 table->cursor->unlock_row();
00302 }
00303 killed_status= session->getKilled();
00304 if (killed_status != Session::NOT_KILLED || session->is_error())
00305 error= 1;
00306
00307 session->set_proc_info("end");
00308 info.end_read_record();
00309
00310 cleanup:
00311
00312 if (reset_auto_increment && (error < 0))
00313 {
00314
00315
00316
00317
00318 int error2= table->cursor->ha_reset_auto_increment(0);
00319
00320 if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
00321 {
00322 table->print_error(error2, MYF(0));
00323 error= 1;
00324 }
00325 }
00326
00327 delete select;
00328 transactional_table= table->cursor->has_transactions();
00329
00330 if (!transactional_table && deleted > 0)
00331 session->transaction.stmt.markModifiedNonTransData();
00332
00333
00334 if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
00335 {
00336 if (session->transaction.stmt.hasModifiedNonTransData())
00337 session->transaction.all.markModifiedNonTransData();
00338 }
00339 assert(transactional_table || !deleted || session->transaction.stmt.hasModifiedNonTransData());
00340 free_underlaid_joins(session, select_lex);
00341
00342 DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
00343 if (error < 0 || (session->lex().ignore && !session->is_fatal_error))
00344 {
00345 session->row_count_func= deleted;
00350 session->main_da.reset_diagnostics_area();
00351 session->my_ok((ha_rows) session->rowCount());
00352 }
00353 session->status_var.deleted_row_count+= deleted;
00354
00355 return (error >= 0 || session->is_error());
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 int prepare_delete(Session *session, TableList *table_list, Item **conds)
00373 {
00374 Select_Lex *select_lex= &session->lex().select_lex;
00375
00376 List<Item> all_fields;
00377
00378 session->lex().allow_sum_func= 0;
00379 if (setup_tables_and_check_access(session, &session->lex().select_lex.context,
00380 &session->lex().select_lex.top_join_list,
00381 table_list,
00382 &select_lex->leaf_tables, false) ||
00383 session->setup_conds(table_list, conds))
00384 return(true);
00385 {
00386 TableList *duplicate;
00387 if ((duplicate= unique_table(table_list, table_list->next_global)))
00388 {
00389 my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
00390 return(true);
00391 }
00392 }
00393
00394 if (select_lex->inner_refs_list.size() &&
00395 fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
00396 return(true);
00397
00398 return(false);
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 bool truncate(Session& session, TableList *table_list)
00412 {
00413 bool error;
00414 TransactionServices &transaction_services= TransactionServices::singleton();
00415
00416 uint64_t save_options= session.options;
00417 table_list->lock_type= TL_WRITE;
00418 session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
00419 init_select(&session.lex());
00420 error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
00421 HA_POS_ERROR, 0L, true);
00422
00423
00424
00425
00426 error= transaction_services.autocommitOrRollback(session, error);
00427 session.options= save_options;
00428
00429 return error;
00430 }
00431
00432 }