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
155
table->covering_keys.reset();
163
156
table->quick_keys.reset(); // Can't use 'only index'
164
select= optimizer::make_select(table, 0, 0, conds, 0, &error);
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
176
if (table->quick_keys.none())
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
197
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
206
usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
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
free_underlaid_joins(session, &session->getLex()->select_lex);
222
DRIZZLE_DELETE_DONE(1, 0);
214
free_underlaid_joins(session, &session->lex->select_lex);
226
218
Filesort has already found and selected the rows we want to delete,
393
374
if (select_lex->inner_refs_list.elements &&
394
375
fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
401
382
/***************************************************************************
383
Delete multiple tables from join
384
***************************************************************************/
386
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
388
handler *file= (handler*)arg;
389
return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
393
make delete specific preparation and checks after opening tables
396
mysql_multi_delete_prepare()
397
session thread handler
404
int mysql_multi_delete_prepare(Session *session)
406
LEX *lex= session->lex;
407
TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
408
TableList *target_tbl;
412
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
415
lex->query_tables also point on local list of DELETE Select_Lex
417
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
418
&session->lex->select_lex.top_join_list,
420
&lex->select_lex.leaf_tables, false))
425
Multi-delete can't be constructed over-union => we always have
426
single SELECT on top and have to check underlying SELECTs of it
428
lex->select_lex.exclude_from_table_unique_test= true;
429
/* Fix tables-to-be-deleted-from list to point at opened tables */
430
for (target_tbl= (TableList*) aux_tables;
432
target_tbl= target_tbl->next_local)
434
target_tbl->table= target_tbl->correspondent_table->table;
435
assert(target_tbl->table);
438
Check that table from which we delete is not used somewhere
439
inside subqueries/view.
442
TableList *duplicate;
443
if ((duplicate= unique_table(session, target_tbl->correspondent_table,
444
lex->query_tables, 0)))
446
my_error(ER_UPDATE_TABLE_USED, MYF(0), target_tbl->correspondent_table->alias);
457
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
458
: delete_tables(dt), deleted(0), found(0),
459
num_of_tables(num_of_tables_arg), error(0),
460
do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
462
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
467
multi_delete::prepare(List<Item> &, Select_Lex_Unit *u)
472
session->set_proc_info("deleting from main table");
478
multi_delete::initialize_tables(JOIN *join)
481
Unique **tempfiles_ptr;
484
if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
487
table_map tables_to_delete_from=0;
488
for (walk= delete_tables; walk; walk= walk->next_local)
489
tables_to_delete_from|= walk->table->map;
492
delete_while_scanning= 1;
493
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
497
if (tab->table->map & tables_to_delete_from)
499
/* We are going to delete from this table */
500
Table *tbl=walk->table=tab->table;
501
walk= walk->next_local;
502
/* Don't use KEYREAD optimization on this table */
504
/* Don't use record cache */
506
tbl->covering_keys.reset();
507
if (tbl->file->has_transactions())
508
transactional_tables= 1;
511
tbl->prepare_for_position();
512
tbl->mark_columns_needed_for_delete();
514
else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
515
walk == delete_tables)
518
We are not deleting from the table we are scanning. In this
519
case send_data() shouldn't delete any rows a we may touch
520
the rows in the deleted table many times
522
delete_while_scanning= 0;
526
tempfiles_ptr= tempfiles;
527
if (delete_while_scanning)
529
table_being_deleted= delete_tables;
530
walk= walk->next_local;
532
for (;walk ;walk= walk->next_local)
534
Table *table=walk->table;
535
*tempfiles_ptr++= new Unique (refpos_order_cmp,
536
(void *) table->file,
537
table->file->ref_length,
538
current_session->variables.sortbuff_size);
540
return(session->is_fatal_error != 0);
544
multi_delete::~multi_delete()
546
for (table_being_deleted= delete_tables;
548
table_being_deleted= table_being_deleted->next_local)
550
Table *table= table_being_deleted->table;
554
for (uint32_t counter= 0; counter < num_of_tables; counter++)
556
if (tempfiles[counter])
557
delete tempfiles[counter];
562
bool multi_delete::send_data(List<Item> &)
564
int secure_counter= delete_while_scanning ? -1 : 0;
565
TableList *del_table;
568
for (del_table= delete_tables;
570
del_table= del_table->next_local, secure_counter++)
572
Table *table= del_table->table;
574
/* Check if we are using outer join and we didn't find the row */
575
if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
578
table->file->position(table->record[0]);
581
if (secure_counter < 0)
583
/* We are scanning the current table */
584
assert(del_table == table_being_deleted);
585
table->status|= STATUS_DELETED;
586
if (!(error=table->file->ha_delete_row(table->record[0])))
589
if (!table->file->has_transactions())
590
session->transaction.stmt.modified_non_trans_table= true;
594
table->file->print_error(error,MYF(0));
600
error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
603
error= 1; // Fatal error
612
void multi_delete::send_error(uint32_t errcode,const char *err)
616
/* First send error what ever it is ... */
617
my_message(errcode, err, MYF(0));
623
void multi_delete::abort()
627
/* the error was handled or nothing deleted and no side effects return */
629
(!session->transaction.stmt.modified_non_trans_table && !deleted))
633
If rows from the first table only has been deleted and it is
634
transactional, just do rollback.
635
The same if all tables are transactional, regardless of where we are.
636
In all other cases do attempt deletes ...
638
if (do_delete && normal_tables &&
639
(table_being_deleted != delete_tables ||
640
!table_being_deleted->table->file->has_transactions()))
643
We have to execute the recorded do_deletes() and write info into the
648
assert(error_handled);
652
if (session->transaction.stmt.modified_non_trans_table)
654
session->transaction.all.modified_non_trans_table= true;
662
Do delete from other tables.
668
int multi_delete::do_deletes()
670
int local_error= 0, counter= 0, tmp_error;
675
do_delete= 0; // Mark called
679
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
682
for (; table_being_deleted;
683
table_being_deleted= table_being_deleted->next_local, counter++)
685
ha_rows last_deleted= deleted;
686
Table *table = table_being_deleted->table;
687
if (tempfiles[counter]->get(table))
694
init_read_record(&info,session,table,NULL,0,1);
696
Ignore any rows not found in reference tables as they may already have
697
been deleted by foreign key handling
699
info.ignore_not_found_rows= 1;
700
will_batch= !table->file->start_bulk_delete();
701
while (!(local_error=info.read_record(&info)) && !session->killed)
703
if ((local_error=table->file->ha_delete_row(table->record[0])))
705
table->file->print_error(local_error,MYF(0));
710
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
714
local_error= tmp_error;
715
table->file->print_error(local_error,MYF(0));
718
if (last_deleted != deleted && !table->file->has_transactions())
719
session->transaction.stmt.modified_non_trans_table= true;
720
end_read_record(&info);
721
if (session->killed && !local_error)
723
if (local_error == -1) // End of file
731
Send ok to the client
737
bool multi_delete::send_eof()
739
Session::killed_state killed_status= Session::NOT_KILLED;
740
session->set_proc_info("deleting from reference tables");
742
/* Does deletes for the last n - 1 tables, returns 0 if ok */
743
int local_error= do_deletes(); // returns 0 if success
745
/* compute a total error to know if something failed */
746
local_error= local_error || error;
747
killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
748
/* reset used flags */
749
session->set_proc_info("end");
751
if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
753
if (session->transaction.stmt.modified_non_trans_table)
754
session->transaction.all.modified_non_trans_table= true;
756
if (local_error != 0)
757
error_handled= true; // to force early leave from ::send_error()
761
session->row_count_func= deleted;
762
session->my_ok((ha_rows) session->row_count_func);
768
/***************************************************************************
403
770
****************************************************************************/
406
773
Optimize delete of all rows by doing a full generate of the table
407
774
This will work even if the .ISM and .ISD tables are destroyed
776
dont_send_ok should be set if:
777
- We should always wants to generate the table (even if the table type
778
normally can't safely do this.
779
- We don't want an ok to be sent to the end user.
780
- We don't want to log the truncate command
781
- If we want to have a name lock on the table on exit without errors.
410
bool truncate(Session& session, TableList *table_list)
784
bool mysql_truncate(Session *session, TableList *table_list, bool dont_send_ok)
786
HA_CREATE_INFO create_info;
787
char path[FN_REFLEN];
413
TransactionServices &transaction_services= TransactionServices::singleton();
415
uint64_t save_options= session.options;
790
uint32_t path_length;
793
memset(&create_info, 0, sizeof(create_info));
794
/* If it is a temporary table, close and regenerate it */
795
if (!dont_send_ok && (table= session->find_temporary_table(table_list)))
797
StorageEngine *table_type= table->s->db_type();
798
TableShare *share= table->s;
800
if (!table_type->check_flag(HTON_BIT_CAN_RECREATE))
803
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
805
session->close_temporary_table(table, false, false); // Don't free share
806
ha_create_table(session, share->normalized_path.str,
807
share->db.str, share->table_name.str, &create_info, 1);
808
// We don't need to call invalidate() because this table is not in cache
809
if ((error= (int) !(open_temporary_table(session, share->path.str,
811
share->table_name.str, 1,
813
(void) rm_temporary_table(table_type, path);
814
share->free_table_share();
817
If we return here we will not have logged the truncation to the bin log
818
and we will not my_ok() to the client.
823
path_length= build_table_filename(path, sizeof(path), table_list->db,
824
table_list->table_name, 0);
829
pthread_mutex_lock(&LOCK_open); /* Recreate table for truncate */
830
error= ha_create_table(session, path, table_list->db, table_list->table_name,
832
pthread_mutex_unlock(&LOCK_open);
840
TRUNCATE must always be statement-based binlogged (not row-based) so
841
we don't test current_stmt_binlog_row_based.
843
write_bin_log(session, true, session->query, session->query_length);
844
session->my_ok(); // This should return record count
846
pthread_mutex_lock(&LOCK_open); /* For truncate delete from hash when finished */
847
unlock_table_name(table_list);
848
pthread_mutex_unlock(&LOCK_open);
852
pthread_mutex_lock(&LOCK_open); /* For truncate delete from hash when finished */
853
unlock_table_name(table_list);
854
pthread_mutex_unlock(&LOCK_open);
859
/* Probably InnoDB table */
860
uint64_t save_options= session->options;
416
861
table_list->lock_type= TL_WRITE;
417
session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
418
init_select(session.getLex());
419
error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
862
session->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
863
ha_enable_transaction(session, false);
864
mysql_init_select(session->lex);
865
error= mysql_delete(session, table_list, (COND*) 0, (SQL_LIST*) 0,
420
866
HA_POS_ERROR, 0L, true);
867
ha_enable_transaction(session, true);
422
869
Safety, in case the engine ignored ha_enable_transaction(false)
423
870
above. Also clears session->transaction.*.
425
error= transaction_services.autocommitOrRollback(session, error);
426
session.options= save_options;
872
error= ha_autocommit_or_rollback(session, error);
874
session->options= save_options;
431
} /* namespace drizzled */