~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Joe Daly
  • Date: 2010-01-06 02:20:42 UTC
  • mto: This revision was merged to the branch mainline in revision 1267.
  • Revision ID: skinny.moey@gmail.com-20100106022042-8ov23wc4aq8f9k7d
rename hash_algorithm to algorithm

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
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 */
15
15
 
16
16
/*
17
17
  Delete of records and truncate of tables.
29
29
#include "drizzled/optimizer/range.h"
30
30
#include "drizzled/records.h"
31
31
#include "drizzled/internal/iocache.h"
32
 
#include "drizzled/transaction_services.h"
33
 
#include "drizzled/filesort.h"
34
32
 
35
 
namespace drizzled
36
 
{
 
33
using namespace drizzled;
37
34
 
38
35
/**
39
36
  Implement DELETE SQL word.
50
47
  int           error;
51
48
  Table         *table;
52
49
  optimizer::SqlSelect *select= NULL;
53
 
  ReadRecord    info;
 
50
  READ_RECORD   info;
54
51
  bool          using_limit=limit != HA_POS_ERROR;
55
52
  bool          transactional_table, const_cond;
56
53
  bool          const_cond_result;
57
54
  ha_rows       deleted= 0;
58
55
  uint32_t usable_index= MAX_KEY;
59
56
  Select_Lex   *select_lex= &session->lex->select_lex;
60
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
57
  Session::killed_state killed_status= Session::NOT_KILLED;
61
58
 
62
59
  if (session->openTablesLock(table_list))
63
60
  {
72
69
  table->map=1;
73
70
 
74
71
  if (mysql_prepare_delete(session, table_list, &conds))
75
 
  {
76
 
    DRIZZLE_DELETE_DONE(1, 0);
77
 
    return true;
78
 
  }
 
72
    goto err;
79
73
 
80
74
  /* check ORDER BY even if it can be ignored */
81
75
  if (order && order->elements)
84
78
    List<Item>   fields;
85
79
    List<Item>   all_fields;
86
80
 
 
81
    memset(&tables, 0, sizeof(tables));
87
82
    tables.table = table;
88
83
    tables.alias = table_list->alias;
89
84
 
90
85
      if (select_lex->setup_ref_array(session, order->elements) ||
91
86
          setup_order(session, select_lex->ref_pointer_array, &tables,
92
 
                    fields, all_fields, (Order*) order->first))
93
 
      {
94
 
        delete select;
95
 
        free_underlaid_joins(session, &session->lex->select_lex);
96
 
        DRIZZLE_DELETE_DONE(1, 0);
97
 
 
98
 
        return true;
99
 
      }
 
87
                    fields, all_fields, (order_st*) order->first))
 
88
    {
 
89
      delete select;
 
90
      free_underlaid_joins(session, &session->lex->select_lex);
 
91
      goto err;
 
92
    }
100
93
  }
101
94
 
102
95
  const_cond= (!conds || conds->const_item());
163
156
  table->quick_keys.reset();            // Can't use 'only index'
164
157
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
165
158
  if (error)
166
 
  {
167
 
    DRIZZLE_DELETE_DONE(1, 0);
168
 
    return true;
169
 
  }
170
 
 
 
159
    goto err;
171
160
  if ((select && select->check_quick(session, false, limit)) || !limit)
172
161
  {
173
162
    delete select;
197
186
  if (order && order->elements)
198
187
  {
199
188
    uint32_t         length= 0;
200
 
    SortField  *sortorder;
 
189
    SORT_FIELD  *sortorder;
201
190
    ha_rows examined_rows;
202
191
 
203
192
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
204
 
      usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
 
193
      usable_index= optimizer::get_index_for_order(table, (order_st*)(order->first), limit);
205
194
 
206
195
    if (usable_index == MAX_KEY)
207
196
    {
208
 
      FileSort filesort(*session);
209
 
      table->sort.io_cache= new internal::IO_CACHE;
210
 
 
211
 
 
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)
 
197
      table->sort.io_cache= new IO_CACHE;
 
198
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
 
199
 
 
200
 
 
201
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
 
202
                                             &length, NULL)) ||
 
203
          (table->sort.found_records = filesort(session, table, sortorder, length,
 
204
                                                select, HA_POS_ERROR, 1,
 
205
                                                &examined_rows))
 
206
          == HA_POS_ERROR)
216
207
      {
217
208
        delete select;
218
209
        free_underlaid_joins(session, &session->lex->select_lex);
219
 
 
220
 
        DRIZZLE_DELETE_DONE(1, 0);
221
 
        return true;
 
210
        goto err;
222
211
      }
223
212
      /*
224
213
        Filesort has already found and selected the rows we want to delete,
235
224
  {
236
225
    delete select;
237
226
    free_underlaid_joins(session, select_lex);
238
 
    DRIZZLE_DELETE_DONE(1, 0);
239
 
    return true;
 
227
    goto err;
240
228
  }
241
229
 
242
230
  if (usable_index==MAX_KEY)
243
 
  {
244
 
    info.init_read_record(session,table,select,1,1);
245
 
  }
 
231
    init_read_record(&info,session,table,select,1,1);
246
232
  else
247
 
  {
248
 
    info.init_read_record_idx(session, table, 1, usable_index);
249
 
  }
 
233
    init_read_record_idx(&info, session, table, 1, usable_index);
250
234
 
251
235
  session->set_proc_info("updating");
252
236
 
253
237
  table->mark_columns_needed_for_delete();
254
238
 
255
 
  while (!(error=info.read_record(&info)) && !session->getKilled() &&
 
239
  while (!(error=info.read_record(&info)) && !session->killed &&
256
240
         ! session->is_error())
257
241
  {
258
242
    // session->is_error() is tested to disallow delete row on error
259
243
    if (!(select && select->skip_record())&& ! session->is_error() )
260
244
    {
261
 
      if (!(error= table->cursor->deleteRecord(table->getInsertRecord())))
 
245
      if (!(error= table->cursor->ha_delete_row(table->record[0])))
262
246
      {
263
247
        deleted++;
264
248
        if (!--limit && using_limit)
285
269
    else
286
270
      table->cursor->unlock_row();  // Row failed selection, release lock on it
287
271
  }
288
 
  killed_status= session->getKilled();
 
272
  killed_status= session->killed;
289
273
  if (killed_status != Session::NOT_KILLED || session->is_error())
290
274
    error= 1;                                   // Aborted
291
275
 
292
276
  session->set_proc_info("end");
293
 
  info.end_read_record();
 
277
  end_read_record(&info);
294
278
 
295
279
cleanup:
296
280
 
313
297
  transactional_table= table->cursor->has_transactions();
314
298
 
315
299
  if (!transactional_table && deleted > 0)
316
 
    session->transaction.stmt.markModifiedNonTransData();
 
300
    session->transaction.stmt.modified_non_trans_table= true;
317
301
 
318
302
  /* See similar binlogging code in sql_update.cc, for comments */
319
 
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
 
303
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
320
304
  {
321
 
    if (session->transaction.stmt.hasModifiedNonTransData())
322
 
      session->transaction.all.markModifiedNonTransData();
 
305
    if (session->transaction.stmt.modified_non_trans_table)
 
306
      session->transaction.all.modified_non_trans_table= true;
323
307
  }
324
 
  assert(transactional_table || !deleted || session->transaction.stmt.hasModifiedNonTransData());
 
308
  assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
325
309
  free_underlaid_joins(session, select_lex);
326
310
 
327
311
  DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
335
319
    session->main_da.reset_diagnostics_area();    
336
320
    session->my_ok((ha_rows) session->row_count_func);
337
321
  }
338
 
  session->status_var.deleted_row_count+= deleted;
339
 
 
340
322
  return (error >= 0 || session->is_error());
 
323
 
 
324
err:
 
325
  DRIZZLE_DELETE_DONE(1, 0);
 
326
  return true;
341
327
}
342
328
 
343
329
 
396
382
bool mysql_truncate(Session& session, TableList *table_list)
397
383
{
398
384
  bool error;
399
 
  TransactionServices &transaction_services= TransactionServices::singleton();
400
385
 
401
386
  uint64_t save_options= session.options;
402
387
  table_list->lock_type= TL_WRITE;
403
388
  session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
 
389
  ha_enable_transaction(&session, false);
404
390
  mysql_init_select(session.lex);
405
391
  error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
406
392
                      HA_POS_ERROR, 0L, true);
 
393
  ha_enable_transaction(&session, true);
407
394
  /*
408
395
    Safety, in case the engine ignored ha_enable_transaction(false)
409
396
    above. Also clears session->transaction.*.
410
397
  */
411
 
  error= transaction_services.autocommitOrRollback(&session, error);
 
398
  error= ha_autocommit_or_rollback(&session, error);
 
399
  ha_commit(&session);
412
400
  session.options= save_options;
413
401
 
414
402
  return error;
415
403
}
416
 
 
417
 
} /* namespace drizzled */