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>
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"
43
42
end of dispatch_command().
46
bool delete_query(Session *session, TableList *table_list, COND *conds,
45
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
47
46
SQL_LIST *order, ha_rows limit, uint64_t,
48
47
bool reset_auto_increment)
56
55
bool const_cond_result;
57
56
ha_rows deleted= 0;
58
57
uint32_t usable_index= MAX_KEY;
59
Select_Lex *select_lex= &session->getLex()->select_lex;
60
Session::killed_state_t killed_status= Session::NOT_KILLED;
58
Select_Lex *select_lex= &session->lex->select_lex;
59
Session::killed_state killed_status= Session::NOT_KILLED;
62
61
if (session->openTablesLock(table_list))
71
70
session->set_proc_info("init");
74
if (prepare_delete(session, table_list, &conds))
76
DRIZZLE_DELETE_DONE(1, 0);
73
if (mysql_prepare_delete(session, table_list, &conds))
80
76
/* check ORDER BY even if it can be ignored */
81
77
if (order && order->elements)
85
81
List<Item> all_fields;
83
memset(&tables, 0, sizeof(tables));
87
84
tables.table = table;
88
85
tables.alias = table_list->alias;
90
87
if (select_lex->setup_ref_array(session, order->elements) ||
91
88
setup_order(session, select_lex->ref_pointer_array, &tables,
92
fields, all_fields, (Order*) order->first))
95
free_underlaid_joins(session, &session->getLex()->select_lex);
96
DRIZZLE_DELETE_DONE(1, 0);
89
fields, all_fields, (order_st*) order->first))
92
free_underlaid_joins(session, &session->lex->select_lex);
102
97
const_cond= (!conds || conds->const_item());
104
select_lex->no_error= session->getLex()->ignore;
99
select_lex->no_error= session->lex->ignore;
106
101
const_cond_result= const_cond && (!conds || conds->val_int());
107
102
if (session->is_error())
163
158
table->quick_keys.reset(); // Can't use 'only index'
164
159
select= optimizer::make_select(table, 0, 0, conds, 0, &error);
167
DRIZZLE_DELETE_DONE(1, 0);
171
162
if ((select && select->check_quick(session, false, limit)) || !limit)
174
165
free_underlaid_joins(session, select_lex);
175
166
session->row_count_func= 0;
176
if (session->is_error())
178
167
DRIZZLE_DELETE_DONE(0, 0);
180
169
* Resetting the Diagnostic area to prevent
183
172
session->main_da.reset_diagnostics_area();
184
session->my_ok((ha_rows) session->rowCount());
173
session->my_ok((ha_rows) session->row_count_func);
186
175
We don't need to call reset_auto_increment in this case, because
187
176
mysql_truncate always gives a NULL conds argument, hence we never
199
188
if (order && order->elements)
201
190
uint32_t length= 0;
202
SortField *sortorder;
191
SORT_FIELD *sortorder;
203
192
ha_rows examined_rows;
205
194
if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
206
usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
195
usable_index= optimizer::get_index_for_order(table, (order_st*)(order->first), limit);
208
197
if (usable_index == MAX_KEY)
210
FileSort filesort(*session);
211
199
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
if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
204
(table->sort.found_records = filesort(session, table, sortorder, length,
205
select, HA_POS_ERROR, 1,
220
free_underlaid_joins(session, &session->getLex()->select_lex);
222
DRIZZLE_DELETE_DONE(1, 0);
210
free_underlaid_joins(session, &session->lex->select_lex);
226
214
Filesort has already found and selected the rows we want to delete,
239
227
free_underlaid_joins(session, select_lex);
240
DRIZZLE_DELETE_DONE(1, 0);
244
231
if (usable_index==MAX_KEY)
246
if ((error= info.init_read_record(session,table,select,1,1)))
248
table->print_error(error, MYF(0));
250
free_underlaid_joins(session, select_lex);
233
info.init_read_record(session,table,select,1,1);
256
if ((error= info.init_read_record_idx(session, table, 1, usable_index)))
258
table->print_error(error, MYF(0));
260
free_underlaid_joins(session, select_lex);
237
info.init_read_record_idx(session, table, 1, usable_index);
265
240
session->set_proc_info("updating");
267
242
table->mark_columns_needed_for_delete();
269
while (!(error=info.read_record(&info)) && !session->getKilled() &&
244
while (!(error=info.read_record(&info)) && !session->killed &&
270
245
! session->is_error())
272
247
// session->is_error() is tested to disallow delete row on error
300
275
table->cursor->unlock_row(); // Row failed selection, release lock on it
302
killed_status= session->getKilled();
277
killed_status= session->killed;
303
278
if (killed_status != Session::NOT_KILLED || session->is_error())
304
279
error= 1; // Aborted
339
314
free_underlaid_joins(session, select_lex);
341
316
DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
342
if (error < 0 || (session->getLex()->ignore && !session->is_fatal_error))
317
if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
344
319
session->row_count_func= deleted;
349
324
session->main_da.reset_diagnostics_area();
350
session->my_ok((ha_rows) session->rowCount());
325
session->my_ok((ha_rows) session->row_count_func);
352
327
session->status_var.deleted_row_count+= deleted;
354
328
return (error >= 0 || session->is_error());
331
DRIZZLE_DELETE_DONE(1, 0);
371
int prepare_delete(Session *session, TableList *table_list, Item **conds)
349
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
373
Select_Lex *select_lex= &session->getLex()->select_lex;
351
Select_Lex *select_lex= &session->lex->select_lex;
375
353
List<Item> all_fields;
377
session->getLex()->allow_sum_func= 0;
378
if (setup_tables_and_check_access(session, &session->getLex()->select_lex.context,
379
&session->getLex()->select_lex.top_join_list,
355
session->lex->allow_sum_func= 0;
356
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
357
&session->lex->select_lex.top_join_list,
381
359
&select_lex->leaf_tables, false) ||
382
360
session->setup_conds(table_list, conds))
407
385
This will work even if the .ISM and .ISD tables are destroyed
410
bool truncate(Session& session, TableList *table_list)
388
bool mysql_truncate(Session& session, TableList *table_list)
413
391
TransactionServices &transaction_services= TransactionServices::singleton();
415
393
uint64_t save_options= session.options;
416
394
table_list->lock_type= TL_WRITE;
417
395
session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
418
init_select(session.getLex());
419
error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
396
mysql_init_select(session.lex);
397
error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
420
398
HA_POS_ERROR, 0L, true);
422
400
Safety, in case the engine ignored ha_enable_transaction(false)
423
401
above. Also clears session->transaction.*.
425
error= transaction_services.autocommitOrRollback(session, error);
403
error= transaction_services.autocommitOrRollback(&session, error);
426
404
session.options= save_options;