153
/* Update the table->file->stats.records number */
154
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
159
/* Update the table->cursor->stats.records number */
160
table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
156
table->covering_keys.clear_all();
157
table->quick_keys.clear_all(); // Can't use 'only index'
158
select=make_select(table, 0, 0, conds, 0, &error);
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);
161
if ((select && select->check_quick(session, safe_update, limit)) || !limit)
167
DRIZZLE_DELETE_DONE(1, 0);
171
if ((select && select->check_quick(session, false, limit)) || !limit)
164
174
free_underlaid_joins(session, select_lex);
165
175
session->row_count_func= 0;
166
DRIZZLE_DELETE_END();
167
my_ok(session, (ha_rows) session->row_count_func);
176
DRIZZLE_DELETE_DONE(0, 0);
178
* Resetting the Diagnostic area to prevent
181
session->main_da.reset_diagnostics_area();
182
session->my_ok((ha_rows) session->row_count_func);
169
184
We don't need to call reset_auto_increment in this case, because
170
185
mysql_truncate always gives a NULL conds argument, hence we never
173
return(0); // Nothing to delete
188
return 0; // Nothing to delete
176
191
/* If running in safe sql mode, don't allow updates without keys */
177
if (table->quick_keys.is_clear_all())
192
if (table->quick_keys.none())
179
194
session->server_status|=SERVER_QUERY_NO_INDEX_USED;
180
if (safe_update && !using_limit)
183
free_underlaid_joins(session, select_lex);
184
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
185
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
189
if (options & OPTION_QUICK)
190
(void) table->file->extra(HA_EXTRA_QUICK);
192
197
if (order && order->elements)
194
199
uint32_t length= 0;
195
SORT_FIELD *sortorder;
200
SortField *sortorder;
196
201
ha_rows examined_rows;
198
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
199
usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
203
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
204
usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
201
206
if (usable_index == MAX_KEY)
203
table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
204
MYF(MY_FAE | MY_ZEROFILL));
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,
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)
214
218
free_underlaid_joins(session, &session->lex->select_lex);
220
DRIZZLE_DELETE_DONE(1, 0);
218
224
Filesort has already found and selected the rows we want to delete,
401
387
/***************************************************************************
402
Delete multiple tables from join
403
***************************************************************************/
405
#define MEM_STRIP_BUF_SIZE current_session->variables.sortbuff_size
407
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
409
handler *file= (handler*)arg;
410
return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
414
make delete specific preparation and checks after opening tables
417
mysql_multi_delete_prepare()
418
session thread handler
425
int mysql_multi_delete_prepare(Session *session)
427
LEX *lex= session->lex;
428
TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
429
TableList *target_tbl;
433
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
436
lex->query_tables also point on local list of DELETE SELECT_LEX
438
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
439
&session->lex->select_lex.top_join_list,
441
&lex->select_lex.leaf_tables, false))
446
Multi-delete can't be constructed over-union => we always have
447
single SELECT on top and have to check underlying SELECTs of it
449
lex->select_lex.exclude_from_table_unique_test= true;
450
/* Fix tables-to-be-deleted-from list to point at opened tables */
451
for (target_tbl= (TableList*) aux_tables;
453
target_tbl= target_tbl->next_local)
455
if (!(target_tbl->table= target_tbl->correspondent_table->table))
457
assert(target_tbl->correspondent_table->merge_underlying_list &&
458
target_tbl->correspondent_table->merge_underlying_list->
460
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
465
Check that table from which we delete is not used somewhere
466
inside subqueries/view.
469
TableList *duplicate;
470
if ((duplicate= unique_table(session, target_tbl->correspondent_table,
471
lex->query_tables, 0)))
473
update_non_unique_table_error(target_tbl->correspondent_table,
474
"DELETE", duplicate);
483
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
484
: delete_tables(dt), deleted(0), found(0),
485
num_of_tables(num_of_tables_arg), error(0),
486
do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
488
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
493
multi_delete::prepare(List<Item> &, SELECT_LEX_UNIT *u)
498
session->set_proc_info("deleting from main table");
504
multi_delete::initialize_tables(JOIN *join)
507
Unique **tempfiles_ptr;
510
if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
513
table_map tables_to_delete_from=0;
514
for (walk= delete_tables; walk; walk= walk->next_local)
515
tables_to_delete_from|= walk->table->map;
518
delete_while_scanning= 1;
519
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
523
if (tab->table->map & tables_to_delete_from)
525
/* We are going to delete from this table */
526
Table *tbl=walk->table=tab->table;
527
walk= walk->next_local;
528
/* Don't use KEYREAD optimization on this table */
530
/* Don't use record cache */
532
tbl->covering_keys.clear_all();
533
if (tbl->file->has_transactions())
534
transactional_tables= 1;
537
tbl->prepare_for_position();
538
tbl->mark_columns_needed_for_delete();
540
else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
541
walk == delete_tables)
544
We are not deleting from the table we are scanning. In this
545
case send_data() shouldn't delete any rows a we may touch
546
the rows in the deleted table many times
548
delete_while_scanning= 0;
552
tempfiles_ptr= tempfiles;
553
if (delete_while_scanning)
555
table_being_deleted= delete_tables;
556
walk= walk->next_local;
558
for (;walk ;walk= walk->next_local)
560
Table *table=walk->table;
561
*tempfiles_ptr++= new Unique (refpos_order_cmp,
562
(void *) table->file,
563
table->file->ref_length,
566
return(session->is_fatal_error != 0);
570
multi_delete::~multi_delete()
572
for (table_being_deleted= delete_tables;
574
table_being_deleted= table_being_deleted->next_local)
576
Table *table= table_being_deleted->table;
580
for (uint32_t counter= 0; counter < num_of_tables; counter++)
582
if (tempfiles[counter])
583
delete tempfiles[counter];
588
bool multi_delete::send_data(List<Item> &)
590
int secure_counter= delete_while_scanning ? -1 : 0;
591
TableList *del_table;
594
for (del_table= delete_tables;
596
del_table= del_table->next_local, secure_counter++)
598
Table *table= del_table->table;
600
/* Check if we are using outer join and we didn't find the row */
601
if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
604
table->file->position(table->record[0]);
607
if (secure_counter < 0)
609
/* We are scanning the current table */
610
assert(del_table == table_being_deleted);
611
table->status|= STATUS_DELETED;
612
if (!(error=table->file->ha_delete_row(table->record[0])))
615
if (!table->file->has_transactions())
616
session->transaction.stmt.modified_non_trans_table= true;
620
table->file->print_error(error,MYF(0));
626
error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
629
error= 1; // Fatal error
638
void multi_delete::send_error(uint32_t errcode,const char *err)
642
/* First send error what ever it is ... */
643
my_message(errcode, err, MYF(0));
649
void multi_delete::abort()
653
/* the error was handled or nothing deleted and no side effects return */
655
(!session->transaction.stmt.modified_non_trans_table && !deleted))
659
If rows from the first table only has been deleted and it is
660
transactional, just do rollback.
661
The same if all tables are transactional, regardless of where we are.
662
In all other cases do attempt deletes ...
664
if (do_delete && normal_tables &&
665
(table_being_deleted != delete_tables ||
666
!table_being_deleted->table->file->has_transactions()))
669
We have to execute the recorded do_deletes() and write info into the
674
assert(error_handled);
678
if (session->transaction.stmt.modified_non_trans_table)
681
there is only side effects; to binlog with the error
683
if (drizzle_bin_log.is_open())
685
session->binlog_query(Session::ROW_QUERY_TYPE,
686
session->query, session->query_length,
687
transactional_tables, false);
689
session->transaction.all.modified_non_trans_table= true;
697
Do delete from other tables.
703
int multi_delete::do_deletes()
705
int local_error= 0, counter= 0, tmp_error;
710
do_delete= 0; // Mark called
714
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
717
for (; table_being_deleted;
718
table_being_deleted= table_being_deleted->next_local, counter++)
720
ha_rows last_deleted= deleted;
721
Table *table = table_being_deleted->table;
722
if (tempfiles[counter]->get(table))
729
init_read_record(&info,session,table,NULL,0,1);
731
Ignore any rows not found in reference tables as they may already have
732
been deleted by foreign key handling
734
info.ignore_not_found_rows= 1;
735
will_batch= !table->file->start_bulk_delete();
736
while (!(local_error=info.read_record(&info)) && !session->killed)
738
if ((local_error=table->file->ha_delete_row(table->record[0])))
740
table->file->print_error(local_error,MYF(0));
745
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
749
local_error= tmp_error;
750
table->file->print_error(local_error,MYF(0));
753
if (last_deleted != deleted && !table->file->has_transactions())
754
session->transaction.stmt.modified_non_trans_table= true;
755
end_read_record(&info);
756
if (session->killed && !local_error)
758
if (local_error == -1) // End of file
766
Send ok to the client
772
bool multi_delete::send_eof()
774
Session::killed_state killed_status= Session::NOT_KILLED;
775
session->set_proc_info("deleting from reference tables");
777
/* Does deletes for the last n - 1 tables, returns 0 if ok */
778
int local_error= do_deletes(); // returns 0 if success
780
/* compute a total error to know if something failed */
781
local_error= local_error || error;
782
killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
783
/* reset used flags */
784
session->set_proc_info("end");
786
if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
788
if (drizzle_bin_log.is_open())
790
if (local_error == 0)
791
session->clear_error();
792
if (session->binlog_query(Session::ROW_QUERY_TYPE,
793
session->query, session->query_length,
794
transactional_tables, false, killed_status) &&
797
local_error=1; // Log write failed: roll back the SQL statement
800
if (session->transaction.stmt.modified_non_trans_table)
801
session->transaction.all.modified_non_trans_table= true;
803
if (local_error != 0)
804
error_handled= true; // to force early leave from ::send_error()
808
session->row_count_func= deleted;
809
::my_ok(session, (ha_rows) session->row_count_func);
815
/***************************************************************************
817
389
****************************************************************************/
820
392
Optimize delete of all rows by doing a full generate of the table
821
393
This will work even if the .ISM and .ISD tables are destroyed
823
dont_send_ok should be set if:
824
- We should always wants to generate the table (even if the table type
825
normally can't safely do this.
826
- We don't want an ok to be sent to the end user.
827
- We don't want to log the truncate command
828
- If we want to have a name lock on the table on exit without errors.
831
bool mysql_truncate(Session *session, TableList *table_list, bool dont_send_ok)
396
bool mysql_truncate(Session& session, TableList *table_list)
833
HA_CREATE_INFO create_info;
834
char path[FN_REFLEN];
837
uint32_t path_length;
840
memset(&create_info, 0, sizeof(create_info));
841
/* If it is a temporary table, close and regenerate it */
842
if (!dont_send_ok && (table= find_temporary_table(session, table_list)))
844
handlerton *table_type= table->s->db_type();
845
TABLE_SHARE *share= table->s;
847
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
850
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
852
close_temporary_table(session, table, 0, 0); // Don't free share
853
ha_create_table(session, share->normalized_path.str,
854
share->db.str, share->table_name.str, &create_info, 1);
855
// We don't need to call invalidate() because this table is not in cache
856
if ((error= (int) !(open_temporary_table(session, share->path.str,
858
share->table_name.str, 1,
860
(void) rm_temporary_table(table_type, path);
861
free_table_share(share);
864
If we return here we will not have logged the truncation to the bin log
865
and we will not my_ok() to the client.
870
path_length= build_table_filename(path, sizeof(path), table_list->db,
871
table_list->table_name, reg_ext, 0);
876
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
877
// crashes, replacement works. *(path + path_length - reg_ext_length)=
879
path[path_length - reg_ext_length] = 0;
880
pthread_mutex_lock(&LOCK_open);
881
error= ha_create_table(session, path, table_list->db, table_list->table_name,
883
pthread_mutex_unlock(&LOCK_open);
891
TRUNCATE must always be statement-based binlogged (not row-based) so
892
we don't test current_stmt_binlog_row_based.
894
write_bin_log(session, true, session->query, session->query_length);
895
my_ok(session); // This should return record count
897
pthread_mutex_lock(&LOCK_open);
898
unlock_table_name(session, table_list);
899
pthread_mutex_unlock(&LOCK_open);
903
pthread_mutex_lock(&LOCK_open);
904
unlock_table_name(session, table_list);
905
pthread_mutex_unlock(&LOCK_open);
910
/* Probably InnoDB table */
911
uint64_t save_options= session->options;
399
TransactionServices &transaction_services= TransactionServices::singleton();
401
uint64_t save_options= session.options;
912
402
table_list->lock_type= TL_WRITE;
913
session->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
914
ha_enable_transaction(session, false);
915
mysql_init_select(session->lex);
916
error= mysql_delete(session, table_list, (COND*) 0, (SQL_LIST*) 0,
403
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,
917
406
HA_POS_ERROR, 0L, true);
918
ha_enable_transaction(session, true);
920
408
Safety, in case the engine ignored ha_enable_transaction(false)
921
409
above. Also clears session->transaction.*.
923
error= ha_autocommit_or_rollback(session, error);
925
session->options= save_options;
411
error= transaction_services.autocommitOrRollback(&session, error);
412
session.options= save_options;
417
} /* namespace drizzled */