19
19
Multi-table deletes were introduced by Monty and Sinisa
22
#include "drizzled/sql_select.h"
23
#include "drizzled/error.h"
24
#include "drizzled/probes.h"
25
#include "drizzled/sql_parse.h"
26
#include "drizzled/sql_base.h"
27
#include "drizzled/lock.h"
28
#include "drizzled/probes.h"
29
#include "drizzled/optimizer/range.h"
30
#include "drizzled/records.h"
31
#include "drizzled/internal/iocache.h"
32
#include "drizzled/transaction_services.h"
33
#include "drizzled/filesort.h"
22
#include <drizzled/sql_select.h>
23
#include <drizzled/error.h>
24
#include <drizzled/probes.h>
25
#include <drizzled/sql_parse.h>
26
#include <drizzled/sql_base.h>
27
#include <drizzled/lock.h>
28
#include <drizzled/probes.h>
29
#include <drizzled/optimizer/range.h>
30
#include <drizzled/records.h>
31
#include <drizzled/internal/iocache.h>
32
#include <drizzled/transaction_services.h>
33
#include <drizzled/filesort.h>
34
#include <drizzled/sql_lex.h>
35
#include <drizzled/diagnostics_area.h>
36
#include <drizzled/statistics_variables.h>
37
#include <drizzled/session/transactions.h>
39
42
Implement DELETE SQL word.
43
46
end of dispatch_command().
46
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
49
bool delete_query(Session *session, TableList *table_list, COND *conds,
47
50
SQL_LIST *order, ha_rows limit, uint64_t,
48
51
bool reset_auto_increment)
52
55
optimizer::SqlSelect *select= NULL;
54
57
bool using_limit=limit != HA_POS_ERROR;
55
bool transactional_table, const_cond;
56
bool const_cond_result;
57
58
ha_rows deleted= 0;
58
59
uint32_t usable_index= MAX_KEY;
59
Select_Lex *select_lex= &session->lex->select_lex;
60
Select_Lex *select_lex= &session->lex().select_lex;
60
61
Session::killed_state_t killed_status= Session::NOT_KILLED;
62
63
if (session->openTablesLock(table_list))
71
72
session->set_proc_info("init");
74
if (mysql_prepare_delete(session, table_list, &conds))
75
if (prepare_delete(session, table_list, &conds))
76
77
DRIZZLE_DELETE_DONE(1, 0);
87
88
tables.table = table;
88
89
tables.alias = table_list->alias;
90
if (select_lex->setup_ref_array(session, order->elements) ||
91
setup_order(session, select_lex->ref_pointer_array, &tables,
92
fields, all_fields, (Order*) order->first))
95
free_underlaid_joins(session, &session->lex->select_lex);
96
DRIZZLE_DELETE_DONE(1, 0);
91
select_lex->setup_ref_array(session, order->elements);
92
if (setup_order(session, select_lex->ref_pointer_array, &tables, fields, all_fields, (Order*) order->first))
95
free_underlaid_joins(session, &session->lex().select_lex);
96
DRIZZLE_DELETE_DONE(1, 0);
102
const_cond= (!conds || conds->const_item());
104
select_lex->no_error= session->lex->ignore;
106
const_cond_result= const_cond && (!conds || conds->val_int());
102
bool const_cond= not conds || conds->const_item();
104
select_lex->no_error= session->lex().ignore;
106
bool const_cond_result= const_cond && (!conds || conds->val_int());
107
107
if (session->is_error())
109
109
/* Error evaluating val_int(). */
174
174
free_underlaid_joins(session, select_lex);
175
175
session->row_count_func= 0;
176
if (session->is_error())
176
178
DRIZZLE_DELETE_DONE(0, 0);
178
180
* Resetting the Diagnostic area to prevent
181
session->main_da.reset_diagnostics_area();
182
session->my_ok((ha_rows) session->row_count_func);
183
session->main_da().reset_diagnostics_area();
184
session->my_ok((ha_rows) session->rowCount());
184
186
We don't need to call reset_auto_increment in this case, because
185
187
mysql_truncate always gives a NULL conds argument, hence we never
197
199
if (order && order->elements)
200
SortField *sortorder;
201
ha_rows examined_rows;
203
201
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
204
202
usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
206
204
if (usable_index == MAX_KEY)
208
206
FileSort filesort(*session);
209
table->sort.io_cache= new internal::IO_CACHE;
212
if (not (sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL)) ||
213
(table->sort.found_records = filesort.run(table, sortorder, length,
214
select, HA_POS_ERROR, 1,
215
examined_rows)) == HA_POS_ERROR)
207
table->sort.io_cache= new internal::io_cache_st;
209
SortField* sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL);
210
ha_rows examined_rows;
211
if ((table->sort.found_records= filesort.run(table, sortorder, length, select, HA_POS_ERROR, 1, examined_rows)) == HA_POS_ERROR)
218
free_underlaid_joins(session, &session->lex->select_lex);
214
free_underlaid_joins(session, &session->lex().select_lex);
220
216
DRIZZLE_DELETE_DONE(1, 0);
242
238
if (usable_index==MAX_KEY)
244
info.init_read_record(session,table,select,1,1);
240
if ((error= info.init_read_record(session,table,select,1,1)))
242
table->print_error(error, MYF(0));
244
free_underlaid_joins(session, select_lex);
248
info.init_read_record_idx(session, table, 1, usable_index);
250
if ((error= info.init_read_record_idx(session, table, 1, usable_index)))
252
table->print_error(error, MYF(0));
254
free_underlaid_joins(session, select_lex);
251
259
session->set_proc_info("updating");
313
transactional_table= table->cursor->has_transactions();
321
bool transactional_table= table->cursor->has_transactions();
315
323
if (!transactional_table && deleted > 0)
316
324
session->transaction.stmt.markModifiedNonTransData();
325
333
free_underlaid_joins(session, select_lex);
327
335
DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
328
if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
336
if (error < 0 || (session->lex().ignore && !session->is_fatal_error))
330
338
session->row_count_func= deleted;
332
340
* Resetting the Diagnostic area to prevent
335
session->main_da.reset_diagnostics_area();
336
session->my_ok((ha_rows) session->row_count_func);
343
session->main_da().reset_diagnostics_area();
344
session->my_ok((ha_rows) session->rowCount());
338
346
session->status_var.deleted_row_count+= deleted;
357
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
365
int prepare_delete(Session *session, TableList *table_list, Item **conds)
359
Select_Lex *select_lex= &session->lex->select_lex;
367
Select_Lex *select_lex= &session->lex().select_lex;
368
session->lex().allow_sum_func= 0;
369
if (setup_tables_and_check_access(session, &session->lex().select_lex.context, &select_lex->top_join_list,
370
table_list, &select_lex->leaf_tables, false) ||
371
session->setup_conds(table_list, conds))
374
if (unique_table(table_list, table_list->next_global))
376
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
361
379
List<Item> all_fields;
363
session->lex->allow_sum_func= 0;
364
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
365
&session->lex->select_lex.top_join_list,
367
&select_lex->leaf_tables, false) ||
368
session->setup_conds(table_list, conds))
371
TableList *duplicate;
372
if ((duplicate= unique_table(table_list, table_list->next_global)))
374
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
379
if (select_lex->inner_refs_list.elements &&
380
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
380
if (select_lex->inner_refs_list.size() && fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
393
392
This will work even if the .ISM and .ISD tables are destroyed
396
bool mysql_truncate(Session& session, TableList *table_list)
395
bool truncate(Session& session, TableList *table_list)
399
TransactionServices &transaction_services= TransactionServices::singleton();
401
397
uint64_t save_options= session.options;
402
398
table_list->lock_type= TL_WRITE;
403
399
session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
404
mysql_init_select(session.lex);
405
error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
406
HA_POS_ERROR, 0L, true);
400
init_select(&session.lex());
401
int error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0, HA_POS_ERROR, 0L, true);
408
403
Safety, in case the engine ignored ha_enable_transaction(false)
409
404
above. Also clears session->transaction.*.
411
error= transaction_services.autocommitOrRollback(&session, error);
406
error= TransactionServices::autocommitOrRollback(session, error);
412
407
session.options= save_options;