~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
17
  Delete of records and truncate of tables.
18
19
  Multi-table deletes were introduced by Monty and Sinisa
20
*/
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
21
#include "config.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
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"
1126.10.18 by Padraig O'Sullivan
Various small build fixes for when dtrace is enabled.
28
#include "drizzled/probes.h"
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
29
#include "drizzled/optimizer/range.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
30
#include "drizzled/records.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
31
#include "drizzled/internal/iocache.h"
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
32
#include "drizzled/transaction_services.h"
1 by brian
clean slate
33
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
34
namespace drizzled
35
{
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
36
1 by brian
clean slate
37
/**
38
  Implement DELETE SQL word.
39
40
  @note Like implementations of other DDL/DML in MySQL, this function
41
  relies on the caller to close the thread tables. This is done in the
42
  end of dispatch_command().
43
*/
44
520.1.22 by Brian Aker
Second pass of thd cleanup
45
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
46
                  SQL_LIST *order, ha_rows limit, uint64_t,
1 by brian
clean slate
47
                  bool reset_auto_increment)
48
{
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
49
  int		error;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
50
  Table		*table;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
51
  optimizer::SqlSelect *select= NULL;
1538 by Brian Aker
Code shuffle on ReadRecord
52
  ReadRecord	info;
1 by brian
clean slate
53
  bool          using_limit=limit != HA_POS_ERROR;
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
54
  bool		transactional_table, const_cond;
1 by brian
clean slate
55
  bool          const_cond_result;
56
  ha_rows	deleted= 0;
482 by Brian Aker
Remove uint.
57
  uint32_t usable_index= MAX_KEY;
846 by Brian Aker
Removing on typedeffed class.
58
  Select_Lex   *select_lex= &session->lex->select_lex;
520.1.21 by Brian Aker
THD -> Session rename
59
  Session::killed_state killed_status= Session::NOT_KILLED;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
60
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
61
  if (session->openTablesLock(table_list))
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
62
  {
63
    DRIZZLE_DELETE_DONE(1, 0);
1109.1.2 by Brian Aker
More from the table patch
64
    return true;
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
65
  }
737 by Brian Aker
Updates for dead code removal (and forced assert() in delete).
66
67
  table= table_list->table;
68
  assert(table);
69
520.1.22 by Brian Aker
Second pass of thd cleanup
70
  session->set_proc_info("init");
1 by brian
clean slate
71
  table->map=1;
72
520.1.22 by Brian Aker
Second pass of thd cleanup
73
  if (mysql_prepare_delete(session, table_list, &conds))
1 by brian
clean slate
74
    goto err;
75
76
  /* check ORDER BY even if it can be ignored */
77
  if (order && order->elements)
78
  {
327.2.4 by Brian Aker
Refactoring table.h
79
    TableList   tables;
1 by brian
clean slate
80
    List<Item>   fields;
81
    List<Item>   all_fields;
82
83
    tables.table = table;
84
    tables.alias = table_list->alias;
85
520.1.22 by Brian Aker
Second pass of thd cleanup
86
      if (select_lex->setup_ref_array(session, order->elements) ||
87
	  setup_order(session, select_lex->ref_pointer_array, &tables,
327.2.3 by Brian Aker
Refactoring of class Table
88
                    fields, all_fields, (order_st*) order->first))
1 by brian
clean slate
89
    {
90
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
91
      free_underlaid_joins(session, &session->lex->select_lex);
1 by brian
clean slate
92
      goto err;
93
    }
94
  }
95
96
  const_cond= (!conds || conds->const_item());
97
520.1.22 by Brian Aker
Second pass of thd cleanup
98
  select_lex->no_error= session->lex->ignore;
1 by brian
clean slate
99
100
  const_cond_result= const_cond && (!conds || conds->val_int());
520.1.22 by Brian Aker
Second pass of thd cleanup
101
  if (session->is_error())
1 by brian
clean slate
102
  {
103
    /* Error evaluating val_int(). */
163 by Brian Aker
Merge Monty's code.
104
    return(true);
1 by brian
clean slate
105
  }
106
107
  /*
108
    Test if the user wants to delete all rows and deletion doesn't have
109
    any side-effects (because of triggers), so we can use optimized
110
    handler::delete_all_rows() method.
111
112
    We implement fast TRUNCATE for InnoDB even if triggers are
113
    present.  TRUNCATE ignores triggers.
114
115
    We can use delete_all_rows() if and only if:
116
    - We allow new functions (not using option --skip-new), and are
117
      not in safe mode (not using option --safe-mode)
118
    - There is no limit clause
119
    - The condition is constant
120
    - If there is a condition, then it it produces a non-zero value
121
    - If the current command is DELETE FROM with no where clause
122
      (i.e., not TRUNCATE) then:
123
      - We should not be binlogging this statement row-based, and
124
      - there should be no delete triggers associated with the table.
125
  */
581 by Brian Aker
Second pass through on replication row patch
126
  if (!using_limit && const_cond_result)
1 by brian
clean slate
127
  {
1208.3.2 by brian
Update for Cursor renaming.
128
    /* Update the table->cursor->stats.records number */
129
    table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
130
    ha_rows const maybe_deleted= table->cursor->stats.records;
131
    if (!(error=table->cursor->ha_delete_all_rows()))
1 by brian
clean slate
132
    {
133
      error= -1;				// ok
134
      deleted= maybe_deleted;
135
      goto cleanup;
136
    }
137
    if (error != HA_ERR_WRONG_COMMAND)
138
    {
1216.1.1 by Brian Aker
Move print_error up to Engine.
139
      table->print_error(error,MYF(0));
1 by brian
clean slate
140
      error=0;
141
      goto cleanup;
142
    }
143
    /* Handler didn't support fast delete; Delete rows one by one */
144
  }
145
  if (conds)
146
  {
147
    Item::cond_result result;
520.1.22 by Brian Aker
Second pass of thd cleanup
148
    conds= remove_eq_conds(session, conds, &result);
1 by brian
clean slate
149
    if (result == Item::COND_FALSE)             // Impossible where
150
      limit= 0;
151
  }
152
1208.3.2 by brian
Update for Cursor renaming.
153
  /* Update the table->cursor->stats.records number */
154
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1 by brian
clean slate
155
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
156
  table->covering_keys.reset();
157
  table->quick_keys.reset();		// Can't use 'only index'
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
158
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
1 by brian
clean slate
159
  if (error)
160
    goto err;
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
161
  if ((select && select->check_quick(session, false, limit)) || !limit)
1 by brian
clean slate
162
  {
163
    delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
164
    free_underlaid_joins(session, select_lex);
165
    session->row_count_func= 0;
1126.10.18 by Padraig O'Sullivan
Various small build fixes for when dtrace is enabled.
166
    DRIZZLE_DELETE_DONE(0, 0);
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
167
    /**
168
     * Resetting the Diagnostic area to prevent
169
     * lp bug# 439719
170
     */
171
    session->main_da.reset_diagnostics_area();
836 by Brian Aker
Fixed session call from function to method.
172
    session->my_ok((ha_rows) session->row_count_func);
1 by brian
clean slate
173
    /*
174
      We don't need to call reset_auto_increment in this case, because
175
      mysql_truncate always gives a NULL conds argument, hence we never
176
      get here.
177
    */
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
178
    return 0; // Nothing to delete
1 by brian
clean slate
179
  }
180
181
  /* If running in safe sql mode, don't allow updates without keys */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
182
  if (table->quick_keys.none())
1 by brian
clean slate
183
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
184
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
1 by brian
clean slate
185
  }
186
187
  if (order && order->elements)
188
  {
482 by Brian Aker
Remove uint.
189
    uint32_t         length= 0;
1711.6.1 by Brian Aker
Style on structure cleanup
190
    SortField  *sortorder;
1 by brian
clean slate
191
    ha_rows examined_rows;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
192
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
193
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
194
      usable_index= optimizer::get_index_for_order(table, (order_st*)(order->first), limit);
1 by brian
clean slate
195
196
    if (usable_index == MAX_KEY)
197
    {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
198
      table->sort.io_cache= new internal::IO_CACHE;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
199
200
327.2.3 by Brian Aker
Refactoring of class Table
201
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
1 by brian
clean slate
202
                                             &length, NULL)) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
203
	  (table->sort.found_records = filesort(session, table, sortorder, length,
1 by brian
clean slate
204
                                                select, HA_POS_ERROR, 1,
205
                                                &examined_rows))
206
	  == HA_POS_ERROR)
207
      {
208
        delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
209
        free_underlaid_joins(session, &session->lex->select_lex);
1 by brian
clean slate
210
        goto err;
211
      }
212
      /*
213
        Filesort has already found and selected the rows we want to delete,
214
        so we don't need the where clause
215
      */
216
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
217
      free_underlaid_joins(session, select_lex);
1 by brian
clean slate
218
      select= 0;
219
    }
220
  }
221
222
  /* If quick select is used, initialize it before retrieving rows. */
223
  if (select && select->quick && select->quick->reset())
224
  {
225
    delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
226
    free_underlaid_joins(session, select_lex);
1 by brian
clean slate
227
    goto err;
228
  }
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
229
1 by brian
clean slate
230
  if (usable_index==MAX_KEY)
1538 by Brian Aker
Code shuffle on ReadRecord
231
  {
232
    info.init_read_record(session,table,select,1,1);
233
  }
1 by brian
clean slate
234
  else
1538 by Brian Aker
Code shuffle on ReadRecord
235
  {
1539.1.3 by Brian Aker
Additional function -> method for readrecord
236
    info.init_read_record_idx(session, table, 1, usable_index);
1538 by Brian Aker
Code shuffle on ReadRecord
237
  }
1 by brian
clean slate
238
520.1.22 by Brian Aker
Second pass of thd cleanup
239
  session->set_proc_info("updating");
1 by brian
clean slate
240
241
  table->mark_columns_needed_for_delete();
242
520.1.22 by Brian Aker
Second pass of thd cleanup
243
  while (!(error=info.read_record(&info)) && !session->killed &&
244
	 ! session->is_error())
1 by brian
clean slate
245
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
246
    // session->is_error() is tested to disallow delete row on error
247
    if (!(select && select->skip_record())&& ! session->is_error() )
1 by brian
clean slate
248
    {
1672.3.6 by Brian Aker
First pass in encapsulating row
249
      if (!(error= table->cursor->deleteRecord(table->getInsertRecord())))
1 by brian
clean slate
250
      {
251
	deleted++;
252
	if (!--limit && using_limit)
253
	{
254
	  error= -1;
255
	  break;
256
	}
257
      }
258
      else
259
      {
1216.1.1 by Brian Aker
Move print_error up to Engine.
260
	table->print_error(error,MYF(0));
1 by brian
clean slate
261
	/*
262
	  In < 4.0.14 we set the error number to 0 here, but that
263
	  was not sensible, because then MySQL would not roll back the
264
	  failed DELETE, and also wrote it to the binlog. For MyISAM
265
	  tables a DELETE probably never should fail (?), but for
266
	  InnoDB it can fail in a FOREIGN KEY error or an
267
	  out-of-tablespace error.
268
	*/
269
 	error= 1;
270
	break;
271
      }
272
    }
273
    else
1208.3.2 by brian
Update for Cursor renaming.
274
      table->cursor->unlock_row();  // Row failed selection, release lock on it
1 by brian
clean slate
275
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
276
  killed_status= session->killed;
277
  if (killed_status != Session::NOT_KILLED || session->is_error())
1 by brian
clean slate
278
    error= 1;					// Aborted
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
279
520.1.22 by Brian Aker
Second pass of thd cleanup
280
  session->set_proc_info("end");
1538 by Brian Aker
Code shuffle on ReadRecord
281
  info.end_read_record();
1 by brian
clean slate
282
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
283
cleanup:
284
1 by brian
clean slate
285
  if (reset_auto_increment && (error < 0))
286
  {
287
    /*
288
      We're really doing a truncate and need to reset the table's
289
      auto-increment counter.
290
    */
1208.3.2 by brian
Update for Cursor renaming.
291
    int error2= table->cursor->ha_reset_auto_increment(0);
1 by brian
clean slate
292
293
    if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
294
    {
1216.1.1 by Brian Aker
Move print_error up to Engine.
295
      table->print_error(error2, MYF(0));
1 by brian
clean slate
296
      error= 1;
297
    }
298
  }
299
300
  delete select;
1208.3.2 by brian
Update for Cursor renaming.
301
  transactional_table= table->cursor->has_transactions();
1 by brian
clean slate
302
303
  if (!transactional_table && deleted > 0)
1273.1.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
304
    session->transaction.stmt.markModifiedNonTransData();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
305
1 by brian
clean slate
306
  /* See similar binlogging code in sql_update.cc, for comments */
1273.1.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
307
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
1 by brian
clean slate
308
  {
1273.1.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
309
    if (session->transaction.stmt.hasModifiedNonTransData())
310
      session->transaction.all.markModifiedNonTransData();
1 by brian
clean slate
311
  }
1273.1.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
312
  assert(transactional_table || !deleted || session->transaction.stmt.hasModifiedNonTransData());
520.1.22 by Brian Aker
Second pass of thd cleanup
313
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
314
1126.10.25 by Padraig O'Sullivan
Updated calls to some dtrace probes to cast the parameter to const char *
315
  DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
520.1.22 by Brian Aker
Second pass of thd cleanup
316
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
1 by brian
clean slate
317
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
318
    session->row_count_func= deleted;
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
319
    /**
320
     * Resetting the Diagnostic area to prevent
321
     * lp bug# 439719
322
     */
1124.2.16 by Diego Medina
uncommented a call to reset_diagnostics_area()
323
    session->main_da.reset_diagnostics_area();    
836 by Brian Aker
Fixed session call from function to method.
324
    session->my_ok((ha_rows) session->row_count_func);
1 by brian
clean slate
325
  }
1625.2.2 by Joe Daly
add counter logic for rows sent/received/inserted/updated
326
  session->status_var.deleted_row_count+= deleted;
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
327
  return (error >= 0 || session->is_error());
1 by brian
clean slate
328
329
err:
1126.10.18 by Padraig O'Sullivan
Various small build fixes for when dtrace is enabled.
330
  DRIZZLE_DELETE_DONE(1, 0);
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
331
  return true;
1 by brian
clean slate
332
}
333
334
335
/*
336
  Prepare items in DELETE statement
337
338
  SYNOPSIS
339
    mysql_prepare_delete()
520.1.22 by Brian Aker
Second pass of thd cleanup
340
    session			- thread handler
1 by brian
clean slate
341
    table_list		- global/local table list
342
    conds		- conditions
343
344
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
345
    false OK
346
    true  error
1 by brian
clean slate
347
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
348
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
1 by brian
clean slate
349
{
846 by Brian Aker
Removing on typedeffed class.
350
  Select_Lex *select_lex= &session->lex->select_lex;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
351
1 by brian
clean slate
352
  List<Item> all_fields;
353
520.1.22 by Brian Aker
Second pass of thd cleanup
354
  session->lex->allow_sum_func= 0;
355
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
356
                                    &session->lex->select_lex.top_join_list,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
357
                                    table_list,
1 by brian
clean slate
358
                                    &select_lex->leaf_tables, false) ||
1109.1.5 by Brian Aker
More extraction from sql_base
359
      session->setup_conds(table_list, conds))
163 by Brian Aker
Merge Monty's code.
360
    return(true);
1 by brian
clean slate
361
  {
327.2.4 by Brian Aker
Refactoring table.h
362
    TableList *duplicate;
1220.1.13 by Brian Aker
Remove mysql_lock_have_duplicate() (we don't have merge, and our partition
363
    if ((duplicate= unique_table(table_list, table_list->next_global)))
1 by brian
clean slate
364
    {
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
365
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
163 by Brian Aker
Merge Monty's code.
366
      return(true);
1 by brian
clean slate
367
    }
368
  }
369
370
  if (select_lex->inner_refs_list.elements &&
520.1.22 by Brian Aker
Second pass of thd cleanup
371
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
51.2.2 by Patrick Galbraith
Removed DBUGs from
372
    return(-1);
1 by brian
clean slate
373
163 by Brian Aker
Merge Monty's code.
374
  return(false);
1 by brian
clean slate
375
}
376
377
378
/***************************************************************************
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
379
  TRUNCATE Table
1 by brian
clean slate
380
****************************************************************************/
381
382
/*
383
  Optimize delete of all rows by doing a full generate of the table
384
  This will work even if the .ISM and .ISD tables are destroyed
385
*/
386
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
387
bool mysql_truncate(Session& session, TableList *table_list)
1 by brian
clean slate
388
{
389
  bool error;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
390
  TransactionServices &transaction_services= TransactionServices::singleton();
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
391
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
392
  uint64_t save_options= session.options;
1 by brian
clean slate
393
  table_list->lock_type= TL_WRITE;
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
394
  session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
395
  mysql_init_select(session.lex);
396
  error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
398.1.8 by Monty Taylor
Enabled -Wlong-long.
397
                      HA_POS_ERROR, 0L, true);
1 by brian
clean slate
398
  /*
163 by Brian Aker
Merge Monty's code.
399
    Safety, in case the engine ignored ha_enable_transaction(false)
520.1.22 by Brian Aker
Second pass of thd cleanup
400
    above. Also clears session->transaction.*.
1 by brian
clean slate
401
  */
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
402
  error= transaction_services.autocommitOrRollback(&session, error);
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
403
  session.options= save_options;
404
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
405
  return error;
1 by brian
clean slate
406
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
407
408
} /* namespace drizzled */