~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Brian Aker
  • Date: 2009-08-18 07:19:56 UTC
  • mfrom: (1116.1.3 stewart)
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090818071956-nfpoe9rp3i7p50kx
Merge my branch from Stewart into one branch

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
/*
18
18
  Single table and multi table updates of tables.
 
19
  Multi-table updates were introduced by Sinisa & Monty
19
20
*/
20
 
 
21
 
#include <config.h>
22
 
 
 
21
#include <drizzled/server_includes.h>
23
22
#include <drizzled/sql_select.h>
24
23
#include <drizzled/error.h>
25
24
#include <drizzled/probes.h>
26
25
#include <drizzled/sql_base.h>
27
 
#include <drizzled/field/epoch.h>
 
26
#include <drizzled/field/timestamp.h>
28
27
#include <drizzled/sql_parse.h>
29
 
#include <drizzled/optimizer/range.h>
30
 
#include <drizzled/records.h>
31
 
#include <drizzled/internal/my_sys.h>
32
 
#include <drizzled/internal/iocache.h>
33
 
#include <drizzled/transaction_services.h>
34
 
#include <drizzled/filesort.h>
35
 
#include <drizzled/plugin/storage_engine.h>
36
28
 
37
 
#include <boost/dynamic_bitset.hpp>
38
29
#include <list>
39
30
 
40
31
using namespace std;
41
32
 
42
 
namespace drizzled
43
 
{
44
33
 
45
34
/**
46
35
  Re-read record if more columns are needed for error message.
47
36
 
48
37
  If we got a duplicate key error, we want to write an error
49
38
  message containing the value of the duplicate key. If we do not have
50
 
  all fields of the key value in getInsertRecord(), we need to re-read the
 
39
  all fields of the key value in record[0], we need to re-read the
51
40
  record with a proper read_set.
52
41
 
53
42
  @param[in] error   error number
56
45
 
57
46
static void prepare_record_for_error_message(int error, Table *table)
58
47
{
59
 
  Field **field_p= NULL;
60
 
  Field *field= NULL;
61
 
  uint32_t keynr= 0;
 
48
  Field **field_p;
 
49
  Field *field;
 
50
  uint32_t keynr;
 
51
  MY_BITMAP unique_map; /* Fields in offended unique. */
 
52
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
62
53
 
63
54
  /*
64
55
    Only duplicate key errors print the key value.
65
56
    If storage engine does always read all columns, we have the value alraedy.
66
57
  */
67
58
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
68
 
      ! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
 
59
      !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
69
60
    return;
70
61
 
71
62
  /*
72
63
    Get the number of the offended index.
73
64
    We will see MAX_KEY if the engine cannot determine the affected index.
74
65
  */
75
 
  if ((keynr= table->get_dup_key(error)) >= MAX_KEY)
 
66
  if ((keynr= table->file->get_dup_key(error)) >= MAX_KEY)
76
67
    return;
77
68
 
78
69
  /* Create unique_map with all fields used by that index. */
79
 
  boost::dynamic_bitset<> unique_map(table->getShare()->sizeFields()); /* Fields in offended unique. */
80
 
  table->mark_columns_used_by_index_no_reset(keynr, unique_map);
 
70
  bitmap_init(&unique_map, unique_map_buf, table->s->fields);
 
71
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
81
72
 
82
73
  /* Subtract read_set and write_set. */
83
 
  unique_map-= *table->read_set;
84
 
  unique_map-= *table->write_set;
 
74
  bitmap_subtract(&unique_map, table->read_set);
 
75
  bitmap_subtract(&unique_map, table->write_set);
85
76
 
86
77
  /*
87
78
    If the unique index uses columns that are neither in read_set
88
79
    nor in write_set, we must re-read the record.
89
80
    Otherwise no need to do anything.
90
81
  */
91
 
  if (unique_map.none())
 
82
  if (bitmap_is_clear_all(&unique_map))
92
83
    return;
93
84
 
94
 
  /* Get identifier of last read record into table->cursor->ref. */
95
 
  table->cursor->position(table->getInsertRecord());
 
85
  /* Get identifier of last read record into table->file->ref. */
 
86
  table->file->position(table->record[0]);
96
87
  /* Add all fields used by unique index to read_set. */
97
 
  *table->read_set|= unique_map;
98
 
  /* Read record that is identified by table->cursor->ref. */
99
 
  (void) table->cursor->rnd_pos(table->getUpdateRecord(), table->cursor->ref);
 
88
  bitmap_union(table->read_set, &unique_map);
 
89
  /* Read record that is identified by table->file->ref. */
 
90
  (void) table->file->rnd_pos(table->record[1], table->file->ref);
100
91
  /* Copy the newly read columns into the new record. */
101
 
  for (field_p= table->getFields(); (field= *field_p); field_p++)
102
 
  {
103
 
    if (unique_map.test(field->position()))
104
 
    {
105
 
      field->copy_from_tmp(table->getShare()->rec_buff_length);
106
 
    }
107
 
  }
 
92
  for (field_p= table->field; (field= *field_p); field_p++)
 
93
    if (bitmap_is_set(&unique_map, field->field_index))
 
94
      field->copy_from_tmp(table->s->rec_buff_length);
108
95
 
109
96
  return;
110
97
}
114
101
  Process usual UPDATE
115
102
 
116
103
  SYNOPSIS
117
 
    update_query()
 
104
    mysql_update()
118
105
    session                     thread handler
119
106
    fields              fields for update
120
107
    values              values of fields for update
121
108
    conds               WHERE clause expression
122
 
    order_num           number of elemen in ORDER BY clause
 
109
    order_num           number of elemen in order_st BY clause
123
110
    order               order_st BY clause list
124
111
    limit               limit clause
125
112
    handle_duplicates   how to handle duplicates
129
116
    1  - error
130
117
*/
131
118
 
132
 
int update_query(Session *session, TableList *table_list,
 
119
int mysql_update(Session *session, TableList *table_list,
133
120
                 List<Item> &fields, List<Item> &values, COND *conds,
134
 
                 uint32_t order_num, Order *order,
 
121
                 uint32_t order_num, order_st *order,
135
122
                 ha_rows limit, enum enum_duplicates,
136
123
                 bool ignore)
137
124
{
138
125
  bool          using_limit= limit != HA_POS_ERROR;
139
 
  bool          used_key_is_modified;
140
 
  bool          transactional_table;
141
 
  int           error= 0;
 
126
  bool          safe_update= test(session->options & OPTION_SAFE_UPDATES);
 
127
  bool          used_key_is_modified, transactional_table, will_batch;
 
128
  bool          can_compare_record;
 
129
  int           error, loc_error;
142
130
  uint          used_index= MAX_KEY, dup_key_found;
143
131
  bool          need_sort= true;
144
132
  ha_rows       updated, found;
145
133
  key_map       old_covering_keys;
146
134
  Table         *table;
147
 
  optimizer::SqlSelect *select= NULL;
148
 
  ReadRecord    info;
149
 
  Select_Lex    *select_lex= &session->getLex()->select_lex;
 
135
  SQL_SELECT    *select;
 
136
  READ_RECORD   info;
 
137
  Select_Lex    *select_lex= &session->lex->select_lex;
150
138
  uint64_t     id;
151
139
  List<Item> all_fields;
152
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
140
  Session::killed_state killed_status= Session::NOT_KILLED;
153
141
 
154
 
  DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
 
142
  DRIZZLE_UPDATE_START();
155
143
  if (session->openTablesLock(table_list))
156
 
  {
157
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
158
144
    return 1;
159
 
  }
160
145
 
161
146
  session->set_proc_info("init");
162
147
  table= table_list->table;
163
148
 
164
149
  /* Calculate "table->covering_keys" based on the WHERE */
165
 
  table->covering_keys= table->getShare()->keys_in_use;
 
150
  table->covering_keys= table->s->keys_in_use;
166
151
  table->quick_keys.reset();
167
152
 
168
 
  if (prepare_update(session, table_list, &conds, order_num, order))
169
 
  {
170
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
171
 
    return 1;
172
 
  }
 
153
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
 
154
    goto abort;
173
155
 
174
156
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
175
157
  /* Check the fields we are going to modify */
176
158
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
177
 
  {
178
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
179
 
    return 1;
180
 
  }
181
 
 
 
159
    goto abort;                               /* purecov: inspected */
182
160
  if (table->timestamp_field)
183
161
  {
184
162
    // Don't set timestamp column if this is modified
185
163
    if (table->timestamp_field->isWriteSet())
186
 
    {
187
164
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
188
 
    }
189
165
    else
190
166
    {
191
167
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
192
168
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
193
 
      {
194
 
        table->setWriteSet(table->timestamp_field->position());
195
 
      }
 
169
        table->setWriteSet(table->timestamp_field->field_index);
196
170
    }
197
171
  }
198
172
 
199
173
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
200
174
  {
201
175
    free_underlaid_joins(session, select_lex);
202
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
203
 
 
204
 
    return 1;
 
176
    goto abort;                               /* purecov: inspected */
205
177
  }
206
178
 
207
179
  if (select_lex->inner_refs_list.elements &&
208
180
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
209
181
  {
210
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
211
 
    return 1;
 
182
    DRIZZLE_UPDATE_END();
 
183
    return(-1);
212
184
  }
213
185
 
214
186
  if (conds)
224
196
    update force the table handler to retrieve write-only fields to be able
225
197
    to compare records and detect data change.
226
198
  */
227
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
199
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
228
200
      table->timestamp_field &&
229
201
      (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
230
202
       table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
231
 
  {
232
 
    *table->read_set|= *table->write_set;
233
 
  }
 
203
    bitmap_union(table->read_set, table->write_set);
234
204
  // Don't count on usage of 'only index' when calculating which key to use
235
205
  table->covering_keys.reset();
236
206
 
237
 
  /* Update the table->cursor->stats.records number */
238
 
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
207
  /* Update the table->file->stats.records number */
 
208
  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
239
209
 
240
 
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
 
210
  select= make_select(table, 0, 0, conds, 0, &error);
241
211
  if (error || !limit ||
242
 
      (select && select->check_quick(session, false, limit)))
 
212
      (select && select->check_quick(session, safe_update, limit)))
243
213
  {
244
214
    delete select;
245
 
    /**
246
 
     * Resetting the Diagnostic area to prevent
247
 
     * lp bug# 439719
248
 
     */
249
 
    session->main_da.reset_diagnostics_area();
250
215
    free_underlaid_joins(session, select_lex);
251
 
    if (error || session->is_error())
252
 
    {
253
 
      DRIZZLE_UPDATE_DONE(1, 0, 0);
254
 
      return 1;
255
 
    }
256
 
    DRIZZLE_UPDATE_DONE(0, 0, 0);
 
216
    if (error)
 
217
      goto abort;                               // Error in where
 
218
    DRIZZLE_UPDATE_END();
257
219
    session->my_ok();                           // No matching records
258
 
    return 0;
 
220
    return(0);
259
221
  }
260
222
  if (!select && limit != HA_POS_ERROR)
261
223
  {
262
 
    if ((used_index= optimizer::get_index_for_order(table, order, limit)) != MAX_KEY)
 
224
    if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY)
263
225
      need_sort= false;
264
226
  }
265
227
  /* If running in safe sql mode, don't allow updates without keys */
266
228
  if (table->quick_keys.none())
267
229
  {
268
230
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
231
    if (safe_update && !using_limit)
 
232
    {
 
233
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
234
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
235
      goto err;
 
236
    }
269
237
  }
270
238
 
271
239
  table->mark_columns_needed_for_update();
276
244
  {
277
245
    used_index= select->quick->index;
278
246
    used_key_is_modified= (!select->quick->unique_key_range() &&
279
 
                          select->quick->is_keys_used(*table->write_set));
 
247
                          select->quick->is_keys_used(table->write_set));
280
248
  }
281
249
  else
282
250
  {
283
251
    used_key_is_modified= 0;
284
252
    if (used_index == MAX_KEY)                  // no index for sort order
285
 
      used_index= table->cursor->key_used_on_scan;
 
253
      used_index= table->file->key_used_on_scan;
286
254
    if (used_index != MAX_KEY)
287
 
      used_key_is_modified= is_key_used(table, used_index, *table->write_set);
 
255
      used_key_is_modified= is_key_used(table, used_index, table->write_set);
288
256
  }
289
257
 
290
258
 
313
281
        NOTE: filesort will call table->prepare_for_position()
314
282
      */
315
283
      uint32_t         length= 0;
316
 
      SortField  *sortorder;
 
284
      SORT_FIELD  *sortorder;
317
285
      ha_rows examined_rows;
318
 
      FileSort filesort(*session);
319
286
 
320
 
      table->sort.io_cache= new internal::IO_CACHE;
 
287
      table->sort.io_cache = new IO_CACHE;
 
288
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
321
289
 
322
290
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
323
 
          (table->sort.found_records= filesort.run(table, sortorder, length,
324
 
                                                   select, limit, 1,
325
 
                                                   examined_rows)) == HA_POS_ERROR)
 
291
          (table->sort.found_records= filesort(session, table, sortorder, length,
 
292
                                               select, limit, 1,
 
293
                                               &examined_rows))
 
294
          == HA_POS_ERROR)
326
295
      {
327
296
        goto err;
328
297
      }
330
299
        Filesort has already found and selected the rows we want to update,
331
300
        so we don't need the where clause
332
301
      */
333
 
      safe_delete(select);
 
302
      delete select;
 
303
      select= 0;
334
304
    }
335
305
    else
336
306
    {
340
310
        update these in a separate loop based on the pointer.
341
311
      */
342
312
 
343
 
      internal::IO_CACHE tempfile;
344
 
      if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
345
 
      {
 
313
      IO_CACHE tempfile;
 
314
      if (open_cached_file(&tempfile, drizzle_tmpdir,TEMP_PREFIX,
 
315
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
346
316
        goto err;
347
 
      }
348
317
 
349
318
      /* If quick select is used, initialize it before retrieving rows. */
350
319
      if (select && select->quick && select->quick->reset())
351
320
        goto err;
352
 
      table->cursor->try_semi_consistent_read(1);
 
321
      table->file->try_semi_consistent_read(1);
353
322
 
354
323
      /*
355
324
        When we get here, we have one of the following options:
363
332
      */
364
333
 
365
334
      if (used_index == MAX_KEY || (select && select->quick))
366
 
      {
367
 
        if ((error= info.init_read_record(session, table, select, 0, true)))
368
 
          goto err;
369
 
      }
 
335
        init_read_record(&info,session,table,select,0,1);
370
336
      else
371
 
      {
372
 
        if ((error= info.init_read_record_idx(session, table, 1, used_index)))
373
 
          goto err;
374
 
      }
 
337
        init_read_record_idx(&info, session, table, 1, used_index);
375
338
 
376
339
      session->set_proc_info("Searching rows for update");
377
340
      ha_rows tmp_limit= limit;
378
341
 
379
 
      while (not(error= info.read_record(&info)) && not session->getKilled())
 
342
      while (!(error=info.read_record(&info)) && !session->killed)
380
343
      {
381
344
        if (!(select && select->skip_record()))
382
345
        {
383
 
          if (table->cursor->was_semi_consistent_read())
 
346
          if (table->file->was_semi_consistent_read())
384
347
            continue;  /* repeat the read of the same row if it still exists */
385
348
 
386
 
          table->cursor->position(table->getInsertRecord());
387
 
          if (my_b_write(&tempfile,table->cursor->ref,
388
 
                         table->cursor->ref_length))
 
349
          table->file->position(table->record[0]);
 
350
          if (my_b_write(&tempfile,table->file->ref,
 
351
                         table->file->ref_length))
389
352
          {
390
 
            error=1;
391
 
            break;
 
353
            error=1; /* purecov: inspected */
 
354
            break; /* purecov: inspected */
392
355
          }
393
356
          if (!--limit && using_limit)
394
357
          {
397
360
          }
398
361
        }
399
362
        else
400
 
          table->cursor->unlock_row();
 
363
          table->file->unlock_row();
401
364
      }
402
 
      if (session->getKilled() && not error)
 
365
      if (session->killed && !error)
403
366
        error= 1;                               // Aborted
404
367
      limit= tmp_limit;
405
 
      table->cursor->try_semi_consistent_read(0);
406
 
      info.end_read_record();
 
368
      table->file->try_semi_consistent_read(0);
 
369
      end_read_record(&info);
407
370
 
408
371
      /* Change select to use tempfile */
409
372
      if (select)
410
373
      {
411
 
        safe_delete(select->quick);
 
374
        delete select->quick;
412
375
        if (select->free_cond)
413
376
          delete select->cond;
 
377
        select->quick=0;
414
378
        select->cond=0;
415
379
      }
416
380
      else
417
381
      {
418
 
        select= new optimizer::SqlSelect();
 
382
        select= new SQL_SELECT;
419
383
        select->head=table;
420
384
      }
421
 
      if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
422
 
        error=1;
423
 
      // Read row ptrs from this cursor
424
 
      memcpy(select->file, &tempfile, sizeof(tempfile));
 
385
      if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
 
386
        error=1; /* purecov: inspected */
 
387
      select->file=tempfile;                    // Read row ptrs from this file
425
388
      if (error >= 0)
426
389
        goto err;
427
390
    }
430
393
  }
431
394
 
432
395
  if (ignore)
433
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
396
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
434
397
 
435
398
  if (select && select->quick && select->quick->reset())
436
399
    goto err;
437
 
  table->cursor->try_semi_consistent_read(1);
438
 
  if ((error= info.init_read_record(session, table, select, 0, true)))
439
 
  {
440
 
    goto err;
441
 
  }
 
400
  table->file->try_semi_consistent_read(1);
 
401
  init_read_record(&info,session,table,select,0,1);
442
402
 
443
403
  updated= found= 0;
444
404
  /*
453
413
  session->cuted_fields= 0L;
454
414
  session->set_proc_info("Updating");
455
415
 
456
 
  transactional_table= table->cursor->has_transactions();
457
 
  session->setAbortOnWarning(test(!ignore));
 
416
  transactional_table= table->file->has_transactions();
 
417
  session->abort_on_warning= test(!ignore);
 
418
  will_batch= !table->file->start_bulk_update();
458
419
 
459
420
  /*
460
421
    Assure that we can use position()
461
422
    if we need to create an error message.
462
423
  */
463
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
 
424
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
464
425
    table->prepare_for_position();
465
426
 
466
 
  while (not (error=info.read_record(&info)) && not session->getKilled())
 
427
  /*
 
428
    We can use compare_record() to optimize away updates if
 
429
    the table handler is returning all columns OR if
 
430
    if all updated columns are read
 
431
  */
 
432
  can_compare_record= (!(table->file->ha_table_flags() &
 
433
                         HA_PARTIAL_COLUMN_READ) ||
 
434
                       bitmap_is_subset(table->write_set, table->read_set));
 
435
 
 
436
  while (!(error=info.read_record(&info)) && !session->killed)
467
437
  {
468
 
    if (not (select && select->skip_record()))
 
438
    if (!(select && select->skip_record()))
469
439
    {
470
 
      if (table->cursor->was_semi_consistent_read())
 
440
      if (table->file->was_semi_consistent_read())
471
441
        continue;  /* repeat the read of the same row if it still exists */
472
442
 
473
443
      table->storeRecord();
474
 
      if (fill_record(session, fields, values))
475
 
        break;
 
444
      if (fill_record(session, fields, values, 0))
 
445
        break; /* purecov: inspected */
476
446
 
477
447
      found++;
478
448
 
479
 
      if (! table->records_are_comparable() || table->compare_records())
 
449
      if (!can_compare_record || table->compare_record())
480
450
      {
481
 
        /* Non-batched update */
482
 
        error= table->cursor->updateRecord(table->getUpdateRecord(),
483
 
                                            table->getInsertRecord());
484
 
 
485
 
        table->auto_increment_field_not_null= false;
486
 
 
 
451
        if (will_batch)
 
452
        {
 
453
          /*
 
454
            Typically a batched handler can execute the batched jobs when:
 
455
            1) When specifically told to do so
 
456
            2) When it is not a good idea to batch anymore
 
457
            3) When it is necessary to send batch for other reasons
 
458
               (One such reason is when READ's must be performed)
 
459
 
 
460
            1) is covered by exec_bulk_update calls.
 
461
            2) and 3) is handled by the bulk_update_row method.
 
462
 
 
463
            bulk_update_row can execute the updates including the one
 
464
            defined in the bulk_update_row or not including the row
 
465
            in the call. This is up to the handler implementation and can
 
466
            vary from call to call.
 
467
 
 
468
            The dup_key_found reports the number of duplicate keys found
 
469
            in those updates actually executed. It only reports those if
 
470
            the extra call with HA_EXTRA_IGNORE_DUP_KEY have been issued.
 
471
            If this hasn't been issued it returns an error code and can
 
472
            ignore this number. Thus any handler that implements batching
 
473
            for UPDATE IGNORE must also handle this extra call properly.
 
474
 
 
475
            If a duplicate key is found on the record included in this
 
476
            call then it should be included in the count of dup_key_found
 
477
            and error should be set to 0 (only if these errors are ignored).
 
478
          */
 
479
          error= table->file->ha_bulk_update_row(table->record[1],
 
480
                                                 table->record[0],
 
481
                                                 &dup_key_found);
 
482
          limit+= dup_key_found;
 
483
          updated-= dup_key_found;
 
484
        }
 
485
        else
 
486
        {
 
487
          /* Non-batched update */
 
488
          error= table->file->ha_update_row(table->record[1],
 
489
                                            table->record[0]);
 
490
        }
487
491
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
488
 
        {
 
492
        {
489
493
          if (error != HA_ERR_RECORD_IS_THE_SAME)
490
494
            updated++;
491
495
          else
492
496
            error= 0;
493
 
        }
494
 
        else if (! ignore ||
495
 
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
496
 
        {
 
497
        }
 
498
        else if (!ignore ||
 
499
                 table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
500
        {
497
501
          /*
498
502
            If (ignore && error is ignorable) we don't have to
499
503
            do anything; otherwise...
500
504
          */
501
505
          myf flags= 0;
502
506
 
503
 
          if (table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
507
          if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
504
508
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
505
509
 
506
510
          prepare_record_for_error_message(error, table);
507
 
          table->print_error(error,MYF(flags));
508
 
          error= 1;
509
 
          break;
510
 
        }
 
511
          table->file->print_error(error,MYF(flags));
 
512
          error= 1;
 
513
          break;
 
514
        }
511
515
      }
512
516
 
513
517
      if (!--limit && using_limit)
514
518
      {
515
 
        error= -1;                              // Simulate end of cursor
516
 
        break;
 
519
        /*
 
520
          We have reached end-of-file in most common situations where no
 
521
          batching has occurred and if batching was supposed to occur but
 
522
          no updates were made and finally when the batch execution was
 
523
          performed without error and without finding any duplicate keys.
 
524
          If the batched updates were performed with errors we need to
 
525
          check and if no error but duplicate key's found we need to
 
526
          continue since those are not counted for in limit.
 
527
        */
 
528
        if (will_batch &&
 
529
            ((error= table->file->exec_bulk_update(&dup_key_found)) ||
 
530
             dup_key_found))
 
531
        {
 
532
          if (error)
 
533
          {
 
534
            /* purecov: begin inspected */
 
535
            /*
 
536
              The handler should not report error of duplicate keys if they
 
537
              are ignored. This is a requirement on batching handlers.
 
538
            */
 
539
            prepare_record_for_error_message(error, table);
 
540
            table->file->print_error(error,MYF(0));
 
541
            error= 1;
 
542
            break;
 
543
            /* purecov: end */
 
544
          }
 
545
          /*
 
546
            Either an error was found and we are ignoring errors or there
 
547
            were duplicate keys found. In both cases we need to correct
 
548
            the counters and continue the loop.
 
549
          */
 
550
          limit= dup_key_found; //limit is 0 when we get here so need to +
 
551
          updated-= dup_key_found;
 
552
        }
 
553
        else
 
554
        {
 
555
          error= -1;                            // Simulate end of file
 
556
          break;
 
557
        }
517
558
      }
518
559
    }
519
560
    else
520
 
      table->cursor->unlock_row();
 
561
      table->file->unlock_row();
521
562
    session->row_count++;
522
563
  }
523
564
  dup_key_found= 0;
529
570
    It's assumed that if an error was set in combination with an effective
530
571
    killed status then the error is due to killing.
531
572
  */
532
 
  killed_status= session->getKilled(); // get the status of the volatile
 
573
  killed_status= session->killed; // get the status of the volatile
533
574
  // simulated killing after the loop must be ineffective for binlogging
534
575
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
535
576
 
536
 
  updated-= dup_key_found;
537
 
  table->cursor->try_semi_consistent_read(0);
 
577
  if (error &&
 
578
      will_batch &&
 
579
      (loc_error= table->file->exec_bulk_update(&dup_key_found)))
 
580
    /*
 
581
      An error has occurred when a batched update was performed and returned
 
582
      an error indication. It cannot be an allowed duplicate key error since
 
583
      we require the batching handler to treat this as a normal behavior.
 
584
 
 
585
      Otherwise we simply remove the number of duplicate keys records found
 
586
      in the batched update.
 
587
    */
 
588
  {
 
589
    /* purecov: begin inspected */
 
590
    prepare_record_for_error_message(loc_error, table);
 
591
    table->file->print_error(loc_error,MYF(ME_FATALERROR));
 
592
    error= 1;
 
593
    /* purecov: end */
 
594
  }
 
595
  else
 
596
    updated-= dup_key_found;
 
597
  if (will_batch)
 
598
    table->file->end_bulk_update();
 
599
  table->file->try_semi_consistent_read(0);
538
600
 
539
601
  if (!transactional_table && updated > 0)
540
 
    session->transaction.stmt.markModifiedNonTransData();
 
602
    session->transaction.stmt.modified_non_trans_table= true;
541
603
 
542
 
  info.end_read_record();
 
604
  end_read_record(&info);
543
605
  delete select;
544
606
  session->set_proc_info("end");
545
 
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
607
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
546
608
 
547
609
  /*
548
610
    error < 0 means really no error at all: we processed all rows until the
549
611
    last one without error. error > 0 means an error (e.g. unique key
550
612
    violation and no IGNORE or REPLACE). error == 0 is also an error (if
551
613
    preparing the record or invoking before triggers fails). See
552
 
    autocommitOrRollback(error>=0) and return(error>=0) below.
 
614
    ha_autocommit_or_rollback(error>=0) and return(error>=0) below.
553
615
    Sometimes we want to binlog even if we updated no rows, in case user used
554
616
    it to be sure master and slave are in same state.
555
617
  */
556
 
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
 
618
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
557
619
  {
558
 
    if (session->transaction.stmt.hasModifiedNonTransData())
559
 
      session->transaction.all.markModifiedNonTransData();
 
620
    if (session->transaction.stmt.modified_non_trans_table)
 
621
      session->transaction.all.modified_non_trans_table= true;
560
622
  }
561
 
  assert(transactional_table || !updated || session->transaction.stmt.hasModifiedNonTransData());
 
623
  assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
562
624
  free_underlaid_joins(session, select_lex);
563
625
 
564
626
  /* If LAST_INSERT_ID(X) was used, report X */
565
627
  id= session->arg_of_last_insert_id_function ?
566
628
    session->first_successful_insert_id_in_prev_stmt : 0;
567
629
 
 
630
  DRIZZLE_UPDATE_END();
568
631
  if (error < 0)
569
632
  {
570
633
    char buff[STRING_BUFFER_USUAL_SIZE];
571
 
    snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
 
634
    sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
572
635
            (ulong) session->cuted_fields);
573
636
    session->row_count_func= updated;
574
 
    /**
575
 
     * Resetting the Diagnostic area to prevent
576
 
     * lp bug# 439719
577
 
     */
578
 
    session->main_da.reset_diagnostics_area();
579
 
    session->my_ok((ulong) session->rowCount(), found, id, buff);
580
 
    session->status_var.updated_row_count+= session->rowCount();
 
637
    session->my_ok((ulong) session->row_count_func, found, id, buff);
581
638
  }
582
 
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;              /* calc cuted fields */
583
 
  session->setAbortOnWarning(false);
584
 
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
585
 
  return ((error >= 0 || session->is_error()) ? 1 : 0);
 
639
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              /* calc cuted fields */
 
640
  session->abort_on_warning= 0;
 
641
  return((error >= 0 || session->is_error()) ? 1 : 0);
586
642
 
587
643
err:
588
 
  if (error != 0)
589
 
    table->print_error(error,MYF(0));
590
 
 
591
644
  delete select;
592
645
  free_underlaid_joins(session, select_lex);
593
646
  if (table->key_read)
594
647
  {
595
648
    table->key_read=0;
596
 
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
649
    table->file->extra(HA_EXTRA_NO_KEYREAD);
597
650
  }
598
 
  session->setAbortOnWarning(false);
 
651
  session->abort_on_warning= 0;
599
652
 
600
 
  DRIZZLE_UPDATE_DONE(1, 0, 0);
601
 
  return 1;
 
653
abort:
 
654
  DRIZZLE_UPDATE_END();
 
655
  return(1);
602
656
}
603
657
 
604
658
/*
605
659
  Prepare items in UPDATE statement
606
660
 
607
661
  SYNOPSIS
608
 
    prepare_update()
 
662
    mysql_prepare_update()
609
663
    session                     - thread handler
610
664
    table_list          - global/local table list
611
665
    conds               - conditions
612
 
    order_num           - number of ORDER BY list entries
613
 
    order               - ORDER BY clause list
 
666
    order_num           - number of order_st BY list entries
 
667
    order               - order_st BY clause list
614
668
 
615
669
  RETURN VALUE
616
670
    false OK
617
671
    true  error
618
672
*/
619
 
bool prepare_update(Session *session, TableList *table_list,
620
 
                         Item **conds, uint32_t order_num, Order *order)
 
673
bool mysql_prepare_update(Session *session, TableList *table_list,
 
674
                         Item **conds, uint32_t order_num, order_st *order)
621
675
{
622
676
  List<Item> all_fields;
623
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
677
  Select_Lex *select_lex= &session->lex->select_lex;
624
678
 
625
 
  session->getLex()->allow_sum_func= 0;
 
679
  session->lex->allow_sum_func= 0;
626
680
 
627
681
  if (setup_tables_and_check_access(session, &select_lex->context,
628
682
                                    &select_lex->top_join_list,
638
692
  /* Check that we are not using table that we are updating in a sub select */
639
693
  {
640
694
    TableList *duplicate;
641
 
    if ((duplicate= unique_table(table_list, table_list->next_global)))
 
695
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
642
696
    {
643
 
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
 
697
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
644
698
      return true;
645
699
    }
646
700
  }
647
701
 
648
702
  return false;
649
703
}
650
 
 
651
 
} /* namespace drizzled */