~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Stewart Smith
  • Date: 2010-03-18 12:01:34 UTC
  • mto: (1666.2.3 build)
  • mto: This revision was merged to the branch mainline in revision 1596.
  • Revision ID: stewart@flamingspork.com-20100318120134-45fdnsw8g3j6c7oy
move RAND() into a plugin

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.
30
30
#include "drizzled/records.h"
31
31
#include "drizzled/internal/iocache.h"
32
32
#include "drizzled/transaction_services.h"
33
 
#include "drizzled/filesort.h"
34
33
 
35
34
namespace drizzled
36
35
{
50
49
  int           error;
51
50
  Table         *table;
52
51
  optimizer::SqlSelect *select= NULL;
53
 
  ReadRecord    info;
 
52
  READ_RECORD   info;
54
53
  bool          using_limit=limit != HA_POS_ERROR;
55
54
  bool          transactional_table, const_cond;
56
55
  bool          const_cond_result;
57
56
  ha_rows       deleted= 0;
58
57
  uint32_t usable_index= MAX_KEY;
59
58
  Select_Lex   *select_lex= &session->lex->select_lex;
60
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
59
  Session::killed_state killed_status= Session::NOT_KILLED;
61
60
 
62
61
  if (session->openTablesLock(table_list))
63
62
  {
72
71
  table->map=1;
73
72
 
74
73
  if (mysql_prepare_delete(session, table_list, &conds))
75
 
  {
76
 
    DRIZZLE_DELETE_DONE(1, 0);
77
 
    return true;
78
 
  }
 
74
    goto err;
79
75
 
80
76
  /* check ORDER BY even if it can be ignored */
81
77
  if (order && order->elements)
84
80
    List<Item>   fields;
85
81
    List<Item>   all_fields;
86
82
 
 
83
    memset(&tables, 0, sizeof(tables));
87
84
    tables.table = table;
88
85
    tables.alias = table_list->alias;
89
86
 
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))
93
 
      {
94
 
        delete select;
95
 
        free_underlaid_joins(session, &session->lex->select_lex);
96
 
        DRIZZLE_DELETE_DONE(1, 0);
97
 
 
98
 
        return true;
99
 
      }
 
89
                    fields, all_fields, (order_st*) order->first))
 
90
    {
 
91
      delete select;
 
92
      free_underlaid_joins(session, &session->lex->select_lex);
 
93
      goto err;
 
94
    }
100
95
  }
101
96
 
102
97
  const_cond= (!conds || conds->const_item());
163
158
  table->quick_keys.reset();            // Can't use 'only index'
164
159
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
165
160
  if (error)
166
 
  {
167
 
    DRIZZLE_DELETE_DONE(1, 0);
168
 
    return true;
169
 
  }
170
 
 
 
161
    goto err;
171
162
  if ((select && select->check_quick(session, false, limit)) || !limit)
172
163
  {
173
164
    delete select;
197
188
  if (order && order->elements)
198
189
  {
199
190
    uint32_t         length= 0;
200
 
    SortField  *sortorder;
 
191
    SORT_FIELD  *sortorder;
201
192
    ha_rows examined_rows;
202
193
 
203
194
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
204
 
      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);
205
196
 
206
197
    if (usable_index == MAX_KEY)
207
198
    {
208
 
      FileSort filesort(*session);
209
199
      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)
 
200
      memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
 
201
 
 
202
 
 
203
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
 
204
                                             &length, NULL)) ||
 
205
          (table->sort.found_records = filesort(session, table, sortorder, length,
 
206
                                                select, HA_POS_ERROR, 1,
 
207
                                                &examined_rows))
 
208
          == HA_POS_ERROR)
216
209
      {
217
210
        delete select;
218
211
        free_underlaid_joins(session, &session->lex->select_lex);
219
 
 
220
 
        DRIZZLE_DELETE_DONE(1, 0);
221
 
        return true;
 
212
        goto err;
222
213
      }
223
214
      /*
224
215
        Filesort has already found and selected the rows we want to delete,
235
226
  {
236
227
    delete select;
237
228
    free_underlaid_joins(session, select_lex);
238
 
    DRIZZLE_DELETE_DONE(1, 0);
239
 
    return true;
 
229
    goto err;
240
230
  }
241
231
 
242
232
  if (usable_index==MAX_KEY)
243
 
  {
244
 
    info.init_read_record(session,table,select,1,1);
245
 
  }
 
233
    init_read_record(&info,session,table,select,1,1);
246
234
  else
247
 
  {
248
 
    info.init_read_record_idx(session, table, 1, usable_index);
249
 
  }
 
235
    init_read_record_idx(&info, session, table, 1, usable_index);
250
236
 
251
237
  session->set_proc_info("updating");
252
238
 
253
239
  table->mark_columns_needed_for_delete();
254
240
 
255
 
  while (!(error=info.read_record(&info)) && !session->getKilled() &&
 
241
  while (!(error=info.read_record(&info)) && !session->killed &&
256
242
         ! session->is_error())
257
243
  {
258
244
    // session->is_error() is tested to disallow delete row on error
259
245
    if (!(select && select->skip_record())&& ! session->is_error() )
260
246
    {
261
 
      if (!(error= table->cursor->deleteRecord(table->getInsertRecord())))
 
247
      if (!(error= table->cursor->ha_delete_row(table->record[0])))
262
248
      {
263
249
        deleted++;
264
250
        if (!--limit && using_limit)
285
271
    else
286
272
      table->cursor->unlock_row();  // Row failed selection, release lock on it
287
273
  }
288
 
  killed_status= session->getKilled();
 
274
  killed_status= session->killed;
289
275
  if (killed_status != Session::NOT_KILLED || session->is_error())
290
276
    error= 1;                                   // Aborted
291
277
 
292
278
  session->set_proc_info("end");
293
 
  info.end_read_record();
 
279
  end_read_record(&info);
294
280
 
295
281
cleanup:
296
282
 
335
321
    session->main_da.reset_diagnostics_area();    
336
322
    session->my_ok((ha_rows) session->row_count_func);
337
323
  }
338
 
  session->status_var.deleted_row_count+= deleted;
339
 
 
340
324
  return (error >= 0 || session->is_error());
 
325
 
 
326
err:
 
327
  DRIZZLE_DELETE_DONE(1, 0);
 
328
  return true;
341
329
}
342
330
 
343
331
 
408
396
    Safety, in case the engine ignored ha_enable_transaction(false)
409
397
    above. Also clears session->transaction.*.
410
398
  */
411
 
  error= transaction_services.autocommitOrRollback(&session, error);
 
399
  error= transaction_services.ha_autocommit_or_rollback(&session, error);
412
400
  session.options= save_options;
413
401
 
414
402
  return error;