~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Prafulla Tekawade
  • Date: 2010-08-06 11:21:12 UTC
  • mto: (1711.1.21 build) (1725.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1714.
  • Revision ID: prafulla_t@users.sourceforge.net-20100806112112-7w5u0s3nx9u67nzt
Fix for Bug 586051

1. test_if_ref method which checks whether predicate is already evaluated
   due to ref/eq_ref access or not was incorrectly removing a predicate 
   that was not implicitly evaluated due to ref access (due to presence of filesort ?)
   It was field=NULL predicate.
   Such predicate should be kept and execution engine will filter out rows
   correctly. Removal of such predicate led to returning of rows which had
   NULL for join/predicate columns.
2. field COMP_OP NULL will always false for all fields except when COMP_OP
   is NULL-safe equality operator. Modified range optimizer to return zero
   row count in such cases.
   Query now does not even run. It returns zero result. As such Fix(1) is not
   required but we might hit that case in some other query (I have not tried it
   yet)
3. Fixed Field::val_str to print "NULL" for literal NULL instead of "0". It
   added lot of confusion while debugging.

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
{
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
200
 
211
201
 
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)
 
202
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
 
203
                                             &length, NULL)) ||
 
204
          (table->sort.found_records = filesort(session, table, sortorder, length,
 
205
                                                select, HA_POS_ERROR, 1,
 
206
                                                &examined_rows))
 
207
          == HA_POS_ERROR)
216
208
      {
217
209
        delete select;
218
210
        free_underlaid_joins(session, &session->lex->select_lex);
219
 
 
220
 
        DRIZZLE_DELETE_DONE(1, 0);
221
 
        return true;
 
211
        goto err;
222
212
      }
223
213
      /*
224
214
        Filesort has already found and selected the rows we want to delete,
235
225
  {
236
226
    delete select;
237
227
    free_underlaid_joins(session, select_lex);
238
 
    DRIZZLE_DELETE_DONE(1, 0);
239
 
    return true;
 
228
    goto err;
240
229
  }
241
230
 
242
231
  if (usable_index==MAX_KEY)
252
241
 
253
242
  table->mark_columns_needed_for_delete();
254
243
 
255
 
  while (!(error=info.read_record(&info)) && !session->getKilled() &&
 
244
  while (!(error=info.read_record(&info)) && !session->killed &&
256
245
         ! session->is_error())
257
246
  {
258
247
    // session->is_error() is tested to disallow delete row on error
285
274
    else
286
275
      table->cursor->unlock_row();  // Row failed selection, release lock on it
287
276
  }
288
 
  killed_status= session->getKilled();
 
277
  killed_status= session->killed;
289
278
  if (killed_status != Session::NOT_KILLED || session->is_error())
290
279
    error= 1;                                   // Aborted
291
280
 
336
325
    session->my_ok((ha_rows) session->row_count_func);
337
326
  }
338
327
  session->status_var.deleted_row_count+= deleted;
339
 
 
340
328
  return (error >= 0 || session->is_error());
 
329
 
 
330
err:
 
331
  DRIZZLE_DELETE_DONE(1, 0);
 
332
  return true;
341
333
}
342
334
 
343
335