12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
Delete of records and truncate of tables.
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"
21
#include <drizzled/server_includes.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"
30
using namespace drizzled;
39
33
Implement DELETE SQL word.
46
40
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
47
SQL_LIST *order, ha_rows limit, uint64_t,
41
SQL_LIST *order, ha_rows limit, uint64_t options,
48
42
bool reset_auto_increment)
52
optimizer::SqlSelect *select= NULL;
54
49
bool using_limit=limit != HA_POS_ERROR;
55
bool transactional_table, const_cond;
50
bool transactional_table, safe_update, const_cond;
56
51
bool const_cond_result;
57
52
ha_rows deleted= 0;
58
53
uint32_t usable_index= MAX_KEY;
59
54
Select_Lex *select_lex= &session->lex->select_lex;
60
Session::killed_state_t killed_status= Session::NOT_KILLED;
55
Session::killed_state killed_status= Session::NOT_KILLED;
62
57
if (session->openTablesLock(table_list))
74
69
if (mysql_prepare_delete(session, table_list, &conds))
76
DRIZZLE_DELETE_DONE(1, 0);
80
72
/* check ORDER BY even if it can be ignored */
81
73
if (order && order->elements)
85
77
List<Item> all_fields;
79
memset(&tables, 0, sizeof(tables));
87
80
tables.table = table;
88
81
tables.alias = table_list->alias;
90
83
if (select_lex->setup_ref_array(session, order->elements) ||
91
84
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);
85
fields, all_fields, (order_st*) order->first))
88
free_underlaid_joins(session, &session->lex->select_lex);
102
93
const_cond= (!conds || conds->const_item());
94
safe_update=test(session->options & OPTION_SAFE_UPDATES);
95
if (safe_update && const_cond)
97
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
98
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
104
102
select_lex->no_error= session->lex->ignore;
162
160
table->covering_keys.reset();
163
161
table->quick_keys.reset(); // Can't use 'only index'
164
select= optimizer::make_select(table, 0, 0, conds, 0, &error);
162
select=make_select(table, 0, 0, conds, 0, &error);
167
DRIZZLE_DELETE_DONE(1, 0);
171
if ((select && select->check_quick(session, false, limit)) || !limit)
165
if ((select && select->check_quick(session, safe_update, limit)) || !limit)
174
168
free_underlaid_joins(session, select_lex);
192
186
if (table->quick_keys.none())
194
188
session->server_status|=SERVER_QUERY_NO_INDEX_USED;
189
if (safe_update && !using_limit)
192
free_underlaid_joins(session, select_lex);
193
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
194
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
198
if (options & OPTION_QUICK)
199
(void) table->cursor->extra(HA_EXTRA_QUICK);
197
201
if (order && order->elements)
199
203
uint32_t length= 0;
200
SortField *sortorder;
204
SORT_FIELD *sortorder;
201
205
ha_rows examined_rows;
203
207
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
204
usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
208
usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
206
210
if (usable_index == MAX_KEY)
208
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)
212
table->sort.io_cache= new IO_CACHE;
213
memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
216
if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
218
(table->sort.found_records = filesort(session, table, sortorder, length,
219
select, HA_POS_ERROR, 1,
218
224
free_underlaid_joins(session, &session->lex->select_lex);
220
DRIZZLE_DELETE_DONE(1, 0);
224
228
Filesort has already found and selected the rows we want to delete,
237
241
free_underlaid_joins(session, select_lex);
238
DRIZZLE_DELETE_DONE(1, 0);
242
244
if (usable_index==MAX_KEY)
244
info.init_read_record(session,table,select,1,1);
245
init_read_record(&info,session,table,select,1,1);
248
info.init_read_record_idx(session, table, 1, usable_index);
247
init_read_record_idx(&info, session, table, 1, usable_index);
251
249
session->set_proc_info("updating");
251
will_batch= !table->cursor->start_bulk_delete();
253
254
table->mark_columns_needed_for_delete();
255
while (!(error=info.read_record(&info)) && !session->getKilled() &&
256
while (!(error=info.read_record(&info)) && !session->killed &&
256
257
! session->is_error())
258
259
// session->is_error() is tested to disallow delete row on error
259
260
if (!(select && select->skip_record())&& ! session->is_error() )
261
if (!(error= table->cursor->deleteRecord(table->getInsertRecord())))
262
if (!(error= table->cursor->ha_delete_row(table->record[0])))
264
265
if (!--limit && using_limit)
286
287
table->cursor->unlock_row(); // Row failed selection, release lock on it
288
killed_status= session->getKilled();
289
killed_status= session->killed;
289
290
if (killed_status != Session::NOT_KILLED || session->is_error())
290
291
error= 1; // Aborted
292
if (will_batch && (loc_error= table->cursor->end_bulk_delete()))
295
table->print_error(loc_error,MYF(0));
292
298
session->set_proc_info("end");
293
info.end_read_record();
299
end_read_record(&info);
300
if (options & OPTION_QUICK)
301
(void) table->cursor->extra(HA_EXTRA_NORMAL);
313
321
transactional_table= table->cursor->has_transactions();
315
323
if (!transactional_table && deleted > 0)
316
session->transaction.stmt.markModifiedNonTransData();
324
session->transaction.stmt.modified_non_trans_table= true;
318
326
/* See similar binlogging code in sql_update.cc, for comments */
319
if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
327
if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
321
if (session->transaction.stmt.hasModifiedNonTransData())
322
session->transaction.all.markModifiedNonTransData();
329
if (session->transaction.stmt.modified_non_trans_table)
330
session->transaction.all.modified_non_trans_table= true;
324
assert(transactional_table || !deleted || session->transaction.stmt.hasModifiedNonTransData());
332
assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
325
333
free_underlaid_joins(session, select_lex);
327
335
DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
335
343
session->main_da.reset_diagnostics_area();
336
344
session->my_ok((ha_rows) session->row_count_func);
338
session->status_var.deleted_row_count+= deleted;
340
346
return (error >= 0 || session->is_error());
349
DRIZZLE_DELETE_DONE(1, 0);
396
406
bool mysql_truncate(Session& session, TableList *table_list)
399
TransactionServices &transaction_services= TransactionServices::singleton();
401
410
uint64_t save_options= session.options;
402
411
table_list->lock_type= TL_WRITE;
403
412
session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
413
ha_enable_transaction(&session, false);
404
414
mysql_init_select(session.lex);
405
415
error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
406
416
HA_POS_ERROR, 0L, true);
417
ha_enable_transaction(&session, true);
408
419
Safety, in case the engine ignored ha_enable_transaction(false)
409
420
above. Also clears session->transaction.*.
411
error= transaction_services.autocommitOrRollback(&session, error);
422
error= ha_autocommit_or_rollback(&session, error);
412
424
session.options= save_options;
417
} /* namespace drizzled */