159
/* Update the table->cursor->stats.records number */
160
table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
152
/* Update the table->file->stats.records number */
153
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
162
table->covering_keys.reset();
163
table->quick_keys.reset(); // Can't use 'only index'
164
select= optimizer::make_select(table, 0, 0, conds, 0, &error);
155
table->covering_keys.clear_all();
156
table->quick_keys.clear_all(); // Can't use 'only index'
157
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)
160
if ((select && select->check_quick(session, safe_update, limit)) || !limit)
174
163
free_underlaid_joins(session, select_lex);
175
164
session->row_count_func= 0;
176
if (session->is_error())
178
DRIZZLE_DELETE_DONE(0, 0);
180
* Resetting the Diagnostic area to prevent
183
session->main_da.reset_diagnostics_area();
184
session->my_ok((ha_rows) session->rowCount());
165
DRIZZLE_DELETE_END();
166
session->my_ok((ha_rows) session->row_count_func);
186
168
We don't need to call reset_auto_increment in this case, because
187
169
mysql_truncate always gives a NULL conds argument, hence we never
190
return 0; // Nothing to delete
172
return(0); // Nothing to delete
193
175
/* If running in safe sql mode, don't allow updates without keys */
194
if (table->quick_keys.none())
176
if (table->quick_keys.is_clear_all())
196
178
session->server_status|=SERVER_QUERY_NO_INDEX_USED;
179
if (safe_update && !using_limit)
182
free_underlaid_joins(session, select_lex);
183
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
184
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
188
if (options & OPTION_QUICK)
189
(void) table->file->extra(HA_EXTRA_QUICK);
199
191
if (order && order->elements)
201
193
uint32_t length= 0;
202
SortField *sortorder;
194
SORT_FIELD *sortorder;
203
195
ha_rows examined_rows;
205
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
206
usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
197
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
198
usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
208
200
if (usable_index == MAX_KEY)
210
FileSort filesort(*session);
211
table->sort.io_cache= new internal::IO_CACHE;
214
if (not (sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL)) ||
215
(table->sort.found_records = filesort.run(table, sortorder, length,
216
select, HA_POS_ERROR, 1,
217
examined_rows)) == HA_POS_ERROR)
202
table->sort.io_cache= new IO_CACHE;
203
memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
206
if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
208
(table->sort.found_records = filesort(session, table, sortorder, length,
209
select, HA_POS_ERROR, 1,
220
214
free_underlaid_joins(session, &session->lex->select_lex);
222
DRIZZLE_DELETE_DONE(1, 0);
226
218
Filesort has already found and selected the rows we want to delete,
314
296
We're really doing a truncate and need to reset the table's
315
297
auto-increment counter.
317
int error2= table->cursor->ha_reset_auto_increment(0);
299
int error2= table->file->ha_reset_auto_increment(0);
319
301
if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
321
table->print_error(error2, MYF(0));
303
table->file->print_error(error2, MYF(0));
327
transactional_table= table->cursor->has_transactions();
311
transactional_table= table->file->has_transactions();
329
313
if (!transactional_table && deleted > 0)
330
session->transaction.stmt.markModifiedNonTransData();
314
session->transaction.stmt.modified_non_trans_table= true;
332
316
/* See similar binlogging code in sql_update.cc, for comments */
333
if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
317
if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
335
if (session->transaction.stmt.hasModifiedNonTransData())
336
session->transaction.all.markModifiedNonTransData();
319
if (session->transaction.stmt.modified_non_trans_table)
320
session->transaction.all.modified_non_trans_table= true;
338
assert(transactional_table || !deleted || session->transaction.stmt.hasModifiedNonTransData());
322
assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
339
323
free_underlaid_joins(session, select_lex);
341
DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
325
DRIZZLE_DELETE_END();
342
326
if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
344
328
session->row_count_func= deleted;
346
* Resetting the Diagnostic area to prevent
349
session->main_da.reset_diagnostics_area();
350
session->my_ok((ha_rows) session->rowCount());
329
session->my_ok((ha_rows) session->row_count_func);
352
session->status_var.deleted_row_count+= deleted;
331
return(error >= 0 || session->is_error());
354
return (error >= 0 || session->is_error());
334
DRIZZLE_DELETE_END();
379
360
&session->lex->select_lex.top_join_list,
381
362
&select_lex->leaf_tables, false) ||
382
session->setup_conds(table_list, conds))
363
setup_conds(session, table_list, select_lex->leaf_tables, conds))
385
366
TableList *duplicate;
386
if ((duplicate= unique_table(table_list, table_list->next_global)))
367
if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
388
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
369
update_non_unique_table_error(table_list, "DELETE", duplicate);
393
374
if (select_lex->inner_refs_list.elements &&
394
375
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
382
/***************************************************************************
383
Delete multiple tables from join
384
***************************************************************************/
386
#define MEM_STRIP_BUF_SIZE current_session->variables.sortbuff_size
388
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
390
handler *file= (handler*)arg;
391
return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
395
make delete specific preparation and checks after opening tables
398
mysql_multi_delete_prepare()
399
session thread handler
406
int mysql_multi_delete_prepare(Session *session)
408
LEX *lex= session->lex;
409
TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
410
TableList *target_tbl;
414
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
417
lex->query_tables also point on local list of DELETE SELECT_LEX
419
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
420
&session->lex->select_lex.top_join_list,
422
&lex->select_lex.leaf_tables, false))
427
Multi-delete can't be constructed over-union => we always have
428
single SELECT on top and have to check underlying SELECTs of it
430
lex->select_lex.exclude_from_table_unique_test= true;
431
/* Fix tables-to-be-deleted-from list to point at opened tables */
432
for (target_tbl= (TableList*) aux_tables;
434
target_tbl= target_tbl->next_local)
436
target_tbl->table= target_tbl->correspondent_table->table;
437
assert(target_tbl->table);
440
Check that table from which we delete is not used somewhere
441
inside subqueries/view.
444
TableList *duplicate;
445
if ((duplicate= unique_table(session, target_tbl->correspondent_table,
446
lex->query_tables, 0)))
448
update_non_unique_table_error(target_tbl->correspondent_table,
449
"DELETE", duplicate);
458
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
459
: delete_tables(dt), deleted(0), found(0),
460
num_of_tables(num_of_tables_arg), error(0),
461
do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
463
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
468
multi_delete::prepare(List<Item> &, SELECT_LEX_UNIT *u)
473
session->set_proc_info("deleting from main table");
479
multi_delete::initialize_tables(JOIN *join)
482
Unique **tempfiles_ptr;
485
if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
488
table_map tables_to_delete_from=0;
489
for (walk= delete_tables; walk; walk= walk->next_local)
490
tables_to_delete_from|= walk->table->map;
493
delete_while_scanning= 1;
494
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
498
if (tab->table->map & tables_to_delete_from)
500
/* We are going to delete from this table */
501
Table *tbl=walk->table=tab->table;
502
walk= walk->next_local;
503
/* Don't use KEYREAD optimization on this table */
505
/* Don't use record cache */
507
tbl->covering_keys.clear_all();
508
if (tbl->file->has_transactions())
509
transactional_tables= 1;
512
tbl->prepare_for_position();
513
tbl->mark_columns_needed_for_delete();
515
else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
516
walk == delete_tables)
519
We are not deleting from the table we are scanning. In this
520
case send_data() shouldn't delete any rows a we may touch
521
the rows in the deleted table many times
523
delete_while_scanning= 0;
527
tempfiles_ptr= tempfiles;
528
if (delete_while_scanning)
530
table_being_deleted= delete_tables;
531
walk= walk->next_local;
533
for (;walk ;walk= walk->next_local)
535
Table *table=walk->table;
536
*tempfiles_ptr++= new Unique (refpos_order_cmp,
537
(void *) table->file,
538
table->file->ref_length,
541
return(session->is_fatal_error != 0);
545
multi_delete::~multi_delete()
547
for (table_being_deleted= delete_tables;
549
table_being_deleted= table_being_deleted->next_local)
551
Table *table= table_being_deleted->table;
555
for (uint32_t counter= 0; counter < num_of_tables; counter++)
557
if (tempfiles[counter])
558
delete tempfiles[counter];
563
bool multi_delete::send_data(List<Item> &)
565
int secure_counter= delete_while_scanning ? -1 : 0;
566
TableList *del_table;
569
for (del_table= delete_tables;
571
del_table= del_table->next_local, secure_counter++)
573
Table *table= del_table->table;
575
/* Check if we are using outer join and we didn't find the row */
576
if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
579
table->file->position(table->record[0]);
582
if (secure_counter < 0)
584
/* We are scanning the current table */
585
assert(del_table == table_being_deleted);
586
table->status|= STATUS_DELETED;
587
if (!(error=table->file->ha_delete_row(table->record[0])))
590
if (!table->file->has_transactions())
591
session->transaction.stmt.modified_non_trans_table= true;
595
table->file->print_error(error,MYF(0));
601
error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
604
error= 1; // Fatal error
613
void multi_delete::send_error(uint32_t errcode,const char *err)
617
/* First send error what ever it is ... */
618
my_message(errcode, err, MYF(0));
624
void multi_delete::abort()
628
/* the error was handled or nothing deleted and no side effects return */
630
(!session->transaction.stmt.modified_non_trans_table && !deleted))
634
If rows from the first table only has been deleted and it is
635
transactional, just do rollback.
636
The same if all tables are transactional, regardless of where we are.
637
In all other cases do attempt deletes ...
639
if (do_delete && normal_tables &&
640
(table_being_deleted != delete_tables ||
641
!table_being_deleted->table->file->has_transactions()))
644
We have to execute the recorded do_deletes() and write info into the
649
assert(error_handled);
653
if (session->transaction.stmt.modified_non_trans_table)
655
session->transaction.all.modified_non_trans_table= true;
663
Do delete from other tables.
669
int multi_delete::do_deletes()
671
int local_error= 0, counter= 0, tmp_error;
676
do_delete= 0; // Mark called
680
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
683
for (; table_being_deleted;
684
table_being_deleted= table_being_deleted->next_local, counter++)
686
ha_rows last_deleted= deleted;
687
Table *table = table_being_deleted->table;
688
if (tempfiles[counter]->get(table))
695
init_read_record(&info,session,table,NULL,0,1);
697
Ignore any rows not found in reference tables as they may already have
698
been deleted by foreign key handling
700
info.ignore_not_found_rows= 1;
701
will_batch= !table->file->start_bulk_delete();
702
while (!(local_error=info.read_record(&info)) && !session->killed)
704
if ((local_error=table->file->ha_delete_row(table->record[0])))
706
table->file->print_error(local_error,MYF(0));
711
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
715
local_error= tmp_error;
716
table->file->print_error(local_error,MYF(0));
719
if (last_deleted != deleted && !table->file->has_transactions())
720
session->transaction.stmt.modified_non_trans_table= true;
721
end_read_record(&info);
722
if (session->killed && !local_error)
724
if (local_error == -1) // End of file
732
Send ok to the client
738
bool multi_delete::send_eof()
740
Session::killed_state killed_status= Session::NOT_KILLED;
741
session->set_proc_info("deleting from reference tables");
743
/* Does deletes for the last n - 1 tables, returns 0 if ok */
744
int local_error= do_deletes(); // returns 0 if success
746
/* compute a total error to know if something failed */
747
local_error= local_error || error;
748
killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
749
/* reset used flags */
750
session->set_proc_info("end");
752
if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
754
if (session->transaction.stmt.modified_non_trans_table)
755
session->transaction.all.modified_non_trans_table= true;
757
if (local_error != 0)
758
error_handled= true; // to force early leave from ::send_error()
762
session->row_count_func= deleted;
763
session->my_ok((ha_rows) session->row_count_func);
401
769
/***************************************************************************
403
771
****************************************************************************/
406
774
Optimize delete of all rows by doing a full generate of the table
407
775
This will work even if the .ISM and .ISD tables are destroyed
777
dont_send_ok should be set if:
778
- We should always wants to generate the table (even if the table type
779
normally can't safely do this.
780
- We don't want an ok to be sent to the end user.
781
- We don't want to log the truncate command
782
- If we want to have a name lock on the table on exit without errors.
410
bool truncate(Session& session, TableList *table_list)
785
bool mysql_truncate(Session *session, TableList *table_list, bool dont_send_ok)
787
HA_CREATE_INFO create_info;
788
char path[FN_REFLEN];
413
TransactionServices &transaction_services= TransactionServices::singleton();
415
uint64_t save_options= session.options;
791
uint32_t path_length;
794
memset(&create_info, 0, sizeof(create_info));
795
/* If it is a temporary table, close and regenerate it */
796
if (!dont_send_ok && (table= find_temporary_table(session, table_list)))
798
handlerton *table_type= table->s->db_type();
799
TABLE_SHARE *share= table->s;
801
if (!ha_check_storage_engine_flag(table_type, HTON_BIT_CAN_RECREATE))
804
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
806
close_temporary_table(session, table, 0, 0); // Don't free share
807
ha_create_table(session, share->normalized_path.str,
808
share->db.str, share->table_name.str, &create_info, 1);
809
// We don't need to call invalidate() because this table is not in cache
810
if ((error= (int) !(open_temporary_table(session, share->path.str,
812
share->table_name.str, 1,
814
(void) rm_temporary_table(table_type, path);
815
free_table_share(share);
818
If we return here we will not have logged the truncation to the bin log
819
and we will not my_ok() to the client.
824
path_length= build_table_filename(path, sizeof(path), table_list->db,
825
table_list->table_name, reg_ext, 0);
830
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
831
// crashes, replacement works. *(path + path_length - reg_ext_length)=
833
path[path_length - reg_ext_length] = 0;
834
pthread_mutex_lock(&LOCK_open);
835
error= ha_create_table(session, path, table_list->db, table_list->table_name,
837
pthread_mutex_unlock(&LOCK_open);
845
TRUNCATE must always be statement-based binlogged (not row-based) so
846
we don't test current_stmt_binlog_row_based.
848
write_bin_log(session, true, session->query, session->query_length);
849
session->my_ok(); // This should return record count
851
pthread_mutex_lock(&LOCK_open);
852
unlock_table_name(session, table_list);
853
pthread_mutex_unlock(&LOCK_open);
857
pthread_mutex_lock(&LOCK_open);
858
unlock_table_name(session, table_list);
859
pthread_mutex_unlock(&LOCK_open);
864
/* Probably InnoDB table */
865
uint64_t save_options= session->options;
416
866
table_list->lock_type= TL_WRITE;
417
session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
418
init_select(session.lex);
419
error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
867
session->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
868
ha_enable_transaction(session, false);
869
mysql_init_select(session->lex);
870
error= mysql_delete(session, table_list, (COND*) 0, (SQL_LIST*) 0,
420
871
HA_POS_ERROR, 0L, true);
872
ha_enable_transaction(session, true);
422
874
Safety, in case the engine ignored ha_enable_transaction(false)
423
875
above. Also clears session->transaction.*.
425
error= transaction_services.autocommitOrRollback(session, error);
426
session.options= save_options;
877
error= ha_autocommit_or_rollback(session, error);
879
session->options= save_options;
431
} /* namespace drizzled */