147
146
Item::cond_result result;
148
conds= remove_eq_conds(thd, conds, &result);
147
conds= remove_eq_conds(session, conds, &result);
149
148
if (result == Item::COND_FALSE) // Impossible where
153
/* Update the table->file->stats.records number */
154
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
152
/* Update the table->cursor->stats.records number */
153
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);
155
table->covering_keys.reset();
156
table->quick_keys.reset(); // Can't use 'only index'
157
select= optimizer::make_select(table, 0, 0, conds, 0, &error);
161
if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
160
if ((select && select->check_quick(session, false, limit)) || !limit)
164
free_underlaid_joins(thd, select_lex);
165
thd->row_count_func= 0;
166
DRIZZLE_DELETE_END();
167
my_ok(thd, (ha_rows) thd->row_count_func);
163
free_underlaid_joins(session, select_lex);
164
session->row_count_func= 0;
165
DRIZZLE_DELETE_DONE(0, 0);
167
* Resetting the Diagnostic area to prevent
170
session->main_da.reset_diagnostics_area();
171
session->my_ok((ha_rows) session->row_count_func);
169
173
We don't need to call reset_auto_increment in this case, because
170
174
mysql_truncate always gives a NULL conds argument, hence we never
173
return(0); // Nothing to delete
177
return 0; // Nothing to delete
176
180
/* If running in safe sql mode, don't allow updates without keys */
177
if (table->quick_keys.is_clear_all())
181
if (table->quick_keys.none())
179
thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
180
if (safe_update && !using_limit)
183
free_underlaid_joins(thd, select_lex);
184
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
185
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
183
session->server_status|=SERVER_QUERY_NO_INDEX_USED;
189
if (options & OPTION_QUICK)
190
(void) table->file->extra(HA_EXTRA_QUICK);
192
186
if (order && order->elements)
195
189
SORT_FIELD *sortorder;
196
190
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*)(order->first), limit);
192
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
193
usable_index= optimizer::get_index_for_order(table, (order_st*)(order->first), limit);
201
195
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*) order->first,
197
table->sort.io_cache= new IO_CACHE;
198
memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
201
if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
207
202
&length, NULL)) ||
208
(table->sort.found_records = filesort(thd, table, sortorder, length,
203
(table->sort.found_records = filesort(session, table, sortorder, length,
209
204
select, HA_POS_ERROR, 1,
214
free_underlaid_joins(thd, &thd->lex->select_lex);
209
free_underlaid_joins(session, &session->lex->select_lex);
414
373
/***************************************************************************
415
Delete multiple tables from join
416
***************************************************************************/
418
#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
420
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
422
handler *file= (handler*)arg;
423
return file->cmp_ref((const uchar*)a, (const uchar*)b);
427
make delete specific preparation and checks after opening tables
430
mysql_multi_delete_prepare()
438
int mysql_multi_delete_prepare(THD *thd)
441
TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
442
TABLE_LIST *target_tbl;
446
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
449
lex->query_tables also point on local list of DELETE SELECT_LEX
451
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
452
&thd->lex->select_lex.top_join_list,
454
&lex->select_lex.leaf_tables, false))
459
Multi-delete can't be constructed over-union => we always have
460
single SELECT on top and have to check underlying SELECTs of it
462
lex->select_lex.exclude_from_table_unique_test= true;
463
/* Fix tables-to-be-deleted-from list to point at opened tables */
464
for (target_tbl= (TABLE_LIST*) aux_tables;
466
target_tbl= target_tbl->next_local)
468
if (!(target_tbl->table= target_tbl->correspondent_table->table))
470
assert(target_tbl->correspondent_table->merge_underlying_list &&
471
target_tbl->correspondent_table->merge_underlying_list->
473
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
478
Check that table from which we delete is not used somewhere
479
inside subqueries/view.
482
TABLE_LIST *duplicate;
483
if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
484
lex->query_tables, 0)))
486
update_non_unique_table_error(target_tbl->correspondent_table,
487
"DELETE", duplicate);
496
multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
497
: delete_tables(dt), deleted(0), found(0),
498
num_of_tables(num_of_tables_arg), error(0),
499
do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
501
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
506
multi_delete::prepare(List<Item> &values __attribute__((unused)),
512
thd_proc_info(thd, "deleting from main table");
518
multi_delete::initialize_tables(JOIN *join)
521
Unique **tempfiles_ptr;
524
if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
527
table_map tables_to_delete_from=0;
528
for (walk= delete_tables; walk; walk= walk->next_local)
529
tables_to_delete_from|= walk->table->map;
532
delete_while_scanning= 1;
533
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
537
if (tab->table->map & tables_to_delete_from)
539
/* We are going to delete from this table */
540
TABLE *tbl=walk->table=tab->table;
541
walk= walk->next_local;
542
/* Don't use KEYREAD optimization on this table */
544
/* Don't use record cache */
546
tbl->covering_keys.clear_all();
547
if (tbl->file->has_transactions())
548
transactional_tables= 1;
551
tbl->prepare_for_position();
552
tbl->mark_columns_needed_for_delete();
554
else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
555
walk == delete_tables)
558
We are not deleting from the table we are scanning. In this
559
case send_data() shouldn't delete any rows a we may touch
560
the rows in the deleted table many times
562
delete_while_scanning= 0;
566
tempfiles_ptr= tempfiles;
567
if (delete_while_scanning)
569
table_being_deleted= delete_tables;
570
walk= walk->next_local;
572
for (;walk ;walk= walk->next_local)
574
TABLE *table=walk->table;
575
*tempfiles_ptr++= new Unique (refpos_order_cmp,
576
(void *) table->file,
577
table->file->ref_length,
580
return(thd->is_fatal_error != 0);
584
multi_delete::~multi_delete()
586
for (table_being_deleted= delete_tables;
588
table_being_deleted= table_being_deleted->next_local)
590
TABLE *table= table_being_deleted->table;
594
for (uint counter= 0; counter < num_of_tables; counter++)
596
if (tempfiles[counter])
597
delete tempfiles[counter];
602
bool multi_delete::send_data(List<Item> &values __attribute__((unused)))
604
int secure_counter= delete_while_scanning ? -1 : 0;
605
TABLE_LIST *del_table;
608
for (del_table= delete_tables;
610
del_table= del_table->next_local, secure_counter++)
612
TABLE *table= del_table->table;
614
/* Check if we are using outer join and we didn't find the row */
615
if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
618
table->file->position(table->record[0]);
621
if (secure_counter < 0)
623
/* We are scanning the current table */
624
assert(del_table == table_being_deleted);
625
table->status|= STATUS_DELETED;
626
if (!(error=table->file->ha_delete_row(table->record[0])))
629
if (!table->file->has_transactions())
630
thd->transaction.stmt.modified_non_trans_table= true;
634
table->file->print_error(error,MYF(0));
640
error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
643
error= 1; // Fatal error
652
void multi_delete::send_error(uint errcode,const char *err)
656
/* First send error what ever it is ... */
657
my_message(errcode, err, MYF(0));
663
void multi_delete::abort()
667
/* the error was handled or nothing deleted and no side effects return */
669
(!thd->transaction.stmt.modified_non_trans_table && !deleted))
673
If rows from the first table only has been deleted and it is
674
transactional, just do rollback.
675
The same if all tables are transactional, regardless of where we are.
676
In all other cases do attempt deletes ...
678
if (do_delete && normal_tables &&
679
(table_being_deleted != delete_tables ||
680
!table_being_deleted->table->file->has_transactions()))
683
We have to execute the recorded do_deletes() and write info into the
688
assert(error_handled);
692
if (thd->transaction.stmt.modified_non_trans_table)
695
there is only side effects; to binlog with the error
697
if (mysql_bin_log.is_open())
699
thd->binlog_query(THD::ROW_QUERY_TYPE,
700
thd->query, thd->query_length,
701
transactional_tables, false);
703
thd->transaction.all.modified_non_trans_table= true;
711
Do delete from other tables.
717
int multi_delete::do_deletes()
719
int local_error= 0, counter= 0, tmp_error;
724
do_delete= 0; // Mark called
728
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
731
for (; table_being_deleted;
732
table_being_deleted= table_being_deleted->next_local, counter++)
734
ha_rows last_deleted= deleted;
735
TABLE *table = table_being_deleted->table;
736
if (tempfiles[counter]->get(table))
743
init_read_record(&info,thd,table,NULL,0,1);
745
Ignore any rows not found in reference tables as they may already have
746
been deleted by foreign key handling
748
info.ignore_not_found_rows= 1;
749
will_batch= !table->file->start_bulk_delete();
750
while (!(local_error=info.read_record(&info)) && !thd->killed)
752
if ((local_error=table->file->ha_delete_row(table->record[0])))
754
table->file->print_error(local_error,MYF(0));
759
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
763
local_error= tmp_error;
764
table->file->print_error(local_error,MYF(0));
767
if (last_deleted != deleted && !table->file->has_transactions())
768
thd->transaction.stmt.modified_non_trans_table= true;
769
end_read_record(&info);
770
if (thd->killed && !local_error)
772
if (local_error == -1) // End of file
780
Send ok to the client
786
bool multi_delete::send_eof()
788
THD::killed_state killed_status= THD::NOT_KILLED;
789
thd_proc_info(thd, "deleting from reference tables");
791
/* Does deletes for the last n - 1 tables, returns 0 if ok */
792
int local_error= do_deletes(); // returns 0 if success
794
/* compute a total error to know if something failed */
795
local_error= local_error || error;
796
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
797
/* reset used flags */
798
thd_proc_info(thd, "end");
800
if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
802
if (mysql_bin_log.is_open())
804
if (local_error == 0)
806
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
807
thd->query, thd->query_length,
808
transactional_tables, false, killed_status) &&
811
local_error=1; // Log write failed: roll back the SQL statement
814
if (thd->transaction.stmt.modified_non_trans_table)
815
thd->transaction.all.modified_non_trans_table= true;
817
if (local_error != 0)
818
error_handled= true; // to force early leave from ::send_error()
822
thd->row_count_func= deleted;
823
::my_ok(thd, (ha_rows) thd->row_count_func);
829
/***************************************************************************
831
375
****************************************************************************/
834
378
Optimize delete of all rows by doing a full generate of the table
835
379
This will work even if the .ISM and .ISD tables are destroyed
837
dont_send_ok should be set if:
838
- We should always wants to generate the table (even if the table type
839
normally can't safely do this.
840
- We don't want an ok to be sent to the end user.
841
- We don't want to log the truncate command
842
- If we want to have a name lock on the table on exit without errors.
845
bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
382
bool mysql_truncate(Session& session, TableList *table_list)
847
HA_CREATE_INFO create_info;
848
char path[FN_REFLEN];
854
memset(&create_info, 0, sizeof(create_info));
855
/* If it is a temporary table, close and regenerate it */
856
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
858
handlerton *table_type= table->s->db_type();
859
TABLE_SHARE *share= table->s;
860
bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
862
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
865
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
867
close_temporary_table(thd, table, 0, 0); // Don't free share
868
ha_create_table(thd, share->normalized_path.str,
869
share->db.str, share->table_name.str, &create_info, 1);
870
// We don't need to call invalidate() because this table is not in cache
871
if ((error= (int) !(open_temporary_table(thd, share->path.str,
873
share->table_name.str, 1,
875
(void) rm_temporary_table(table_type, path, frm_only);
876
free_table_share(share);
877
my_free((char*) table,MYF(0));
879
If we return here we will not have logged the truncation to the bin log
880
and we will not my_ok() to the client.
885
path_length= build_table_filename(path, sizeof(path), table_list->db,
886
table_list->table_name, reg_ext, 0);
890
enum legacy_db_type table_type;
891
mysql_frm_type(thd, path, &table_type);
892
if (table_type == DB_TYPE_UNKNOWN)
894
my_error(ER_NO_SUCH_TABLE, MYF(0),
895
table_list->db, table_list->table_name);
899
if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, table_type),
903
if (lock_and_wait_for_table_name(thd, table_list))
907
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
908
// crashes, replacement works. *(path + path_length - reg_ext_length)=
910
path[path_length - reg_ext_length] = 0;
911
VOID(pthread_mutex_lock(&LOCK_open));
912
error= ha_create_table(thd, path, table_list->db, table_list->table_name,
914
VOID(pthread_mutex_unlock(&LOCK_open));
922
TRUNCATE must always be statement-based binlogged (not row-based) so
923
we don't test current_stmt_binlog_row_based.
925
write_bin_log(thd, true, thd->query, thd->query_length);
926
my_ok(thd); // This should return record count
928
VOID(pthread_mutex_lock(&LOCK_open));
929
unlock_table_name(thd, table_list);
930
VOID(pthread_mutex_unlock(&LOCK_open));
934
VOID(pthread_mutex_lock(&LOCK_open));
935
unlock_table_name(thd, table_list);
936
VOID(pthread_mutex_unlock(&LOCK_open));
941
/* Probably InnoDB table */
942
uint64_t save_options= thd->options;
386
uint64_t save_options= session.options;
943
387
table_list->lock_type= TL_WRITE;
944
thd->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
945
ha_enable_transaction(thd, false);
946
mysql_init_select(thd->lex);
947
bool save_binlog_row_based= thd->current_stmt_binlog_row_based;
948
thd->clear_current_stmt_binlog_row_based();
949
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
950
HA_POS_ERROR, 0LL, true);
951
ha_enable_transaction(thd, true);
388
session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
389
ha_enable_transaction(&session, false);
390
mysql_init_select(session.lex);
391
error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
392
HA_POS_ERROR, 0L, true);
393
ha_enable_transaction(&session, true);
953
395
Safety, in case the engine ignored ha_enable_transaction(false)
954
above. Also clears thd->transaction.*.
396
above. Also clears session->transaction.*.
956
error= ha_autocommit_or_rollback(thd, error);
958
thd->options= save_options;
959
thd->current_stmt_binlog_row_based= save_binlog_row_based;
398
error= ha_autocommit_or_rollback(&session, error);
400
session.options= save_options;