~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Brian Aker
  • Date: 2009-05-21 19:15:01 UTC
  • mfrom: (991.1.12 for-brian)
  • Revision ID: brian@gaz-20090521191501-u5qe56byfubioj1r
Merge Stewart

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
19
  Multi-table updates were introduced by Sinisa & Monty
20
20
*/
21
 
#include "config.h"
22
 
#include "drizzled/sql_select.h"
23
 
#include "drizzled/error.h"
24
 
#include "drizzled/probes.h"
25
 
#include "drizzled/sql_base.h"
26
 
#include "drizzled/field/timestamp.h"
27
 
#include "drizzled/sql_parse.h"
28
 
#include "drizzled/optimizer/range.h"
29
 
#include "drizzled/records.h"
30
 
#include "drizzled/internal/my_sys.h"
31
 
#include "drizzled/internal/iocache.h"
32
 
#include "drizzled/transaction_services.h"
33
 
#include "drizzled/filesort.h"
 
21
#include <drizzled/server_includes.h>
 
22
#include <drizzled/sql_select.h>
 
23
#include <drizzled/error.h>
 
24
#include <drizzled/probes.h>
 
25
#include <drizzled/sql_base.h>
 
26
#include <drizzled/field/timestamp.h>
34
27
 
35
 
#include <boost/dynamic_bitset.hpp>
36
28
#include <list>
37
29
 
38
30
using namespace std;
39
31
 
40
 
namespace drizzled
 
32
/*
 
33
  check that all fields are real fields
 
34
 
 
35
  SYNOPSIS
 
36
    check_fields()
 
37
    session             thread handler
 
38
    items           Items for check
 
39
 
 
40
  RETURN
 
41
    true  Items can't be used in UPDATE
 
42
    false Items are OK
 
43
*/
 
44
 
 
45
static bool check_fields(Session *session, List<Item> &items)
41
46
{
 
47
  List_iterator<Item> it(items);
 
48
  Item *item;
 
49
  Item_field *field;
 
50
 
 
51
  while ((item= it++))
 
52
  {
 
53
    if (!(field= item->filed_for_view_update()))
 
54
    {
 
55
      /* item has name, because it comes from VIEW SELECT list */
 
56
      my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
 
57
      return true;
 
58
    }
 
59
    /*
 
60
      we make temporary copy of Item_field, to avoid influence of changing
 
61
      result_field on Item_ref which refer on this field
 
62
    */
 
63
    session->change_item_tree(it.ref(), new Item_field(session, field));
 
64
  }
 
65
  return false;
 
66
}
 
67
 
42
68
 
43
69
/**
44
70
  Re-read record if more columns are needed for error message.
45
71
 
46
72
  If we got a duplicate key error, we want to write an error
47
73
  message containing the value of the duplicate key. If we do not have
48
 
  all fields of the key value in getInsertRecord(), we need to re-read the
 
74
  all fields of the key value in record[0], we need to re-read the
49
75
  record with a proper read_set.
50
76
 
51
77
  @param[in] error   error number
54
80
 
55
81
static void prepare_record_for_error_message(int error, Table *table)
56
82
{
57
 
  Field **field_p= NULL;
58
 
  Field *field= NULL;
59
 
  uint32_t keynr= 0;
 
83
  Field **field_p;
 
84
  Field *field;
 
85
  uint32_t keynr;
 
86
  MY_BITMAP unique_map; /* Fields in offended unique. */
 
87
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
60
88
 
61
89
  /*
62
90
    Only duplicate key errors print the key value.
63
91
    If storage engine does always read all columns, we have the value alraedy.
64
92
  */
65
93
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
66
 
      ! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
 
94
      !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
67
95
    return;
68
96
 
69
97
  /*
70
98
    Get the number of the offended index.
71
99
    We will see MAX_KEY if the engine cannot determine the affected index.
72
100
  */
73
 
  if ((keynr= table->get_dup_key(error)) >= MAX_KEY)
 
101
  if ((keynr= table->file->get_dup_key(error)) >= MAX_KEY)
74
102
    return;
75
103
 
76
104
  /* Create unique_map with all fields used by that index. */
77
 
  boost::dynamic_bitset<> unique_map(table->getShare()->sizeFields()); /* Fields in offended unique. */
78
 
  table->mark_columns_used_by_index_no_reset(keynr, unique_map);
 
105
  bitmap_init(&unique_map, unique_map_buf, table->s->fields, false);
 
106
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
79
107
 
80
108
  /* Subtract read_set and write_set. */
81
 
  unique_map-= *table->read_set;
82
 
  unique_map-= *table->write_set;
 
109
  bitmap_subtract(&unique_map, table->read_set);
 
110
  bitmap_subtract(&unique_map, table->write_set);
83
111
 
84
112
  /*
85
113
    If the unique index uses columns that are neither in read_set
86
114
    nor in write_set, we must re-read the record.
87
115
    Otherwise no need to do anything.
88
116
  */
89
 
  if (unique_map.none())
 
117
  if (bitmap_is_clear_all(&unique_map))
90
118
    return;
91
119
 
92
 
  /* Get identifier of last read record into table->cursor->ref. */
93
 
  table->cursor->position(table->getInsertRecord());
 
120
  /* Get identifier of last read record into table->file->ref. */
 
121
  table->file->position(table->record[0]);
94
122
  /* Add all fields used by unique index to read_set. */
95
 
  *table->read_set|= unique_map;
96
 
  /* Read record that is identified by table->cursor->ref. */
97
 
  (void) table->cursor->rnd_pos(table->getUpdateRecord(), table->cursor->ref);
 
123
  bitmap_union(table->read_set, &unique_map);
 
124
  /* Read record that is identified by table->file->ref. */
 
125
  (void) table->file->rnd_pos(table->record[1], table->file->ref);
98
126
  /* Copy the newly read columns into the new record. */
99
 
  for (field_p= table->getFields(); (field= *field_p); field_p++)
100
 
  {
101
 
    if (unique_map.test(field->position()))
102
 
    {
103
 
      field->copy_from_tmp(table->getShare()->rec_buff_length);
104
 
    }
105
 
  }
 
127
  for (field_p= table->field; (field= *field_p); field_p++)
 
128
    if (bitmap_is_set(&unique_map, field->field_index))
 
129
      field->copy_from_tmp(table->s->rec_buff_length);
106
130
 
107
131
  return;
108
132
}
117
141
    fields              fields for update
118
142
    values              values of fields for update
119
143
    conds               WHERE clause expression
120
 
    order_num           number of elemen in ORDER BY clause
 
144
    order_num           number of elemen in order_st BY clause
121
145
    order               order_st BY clause list
122
146
    limit               limit clause
123
147
    handle_duplicates   how to handle duplicates
129
153
 
130
154
int mysql_update(Session *session, TableList *table_list,
131
155
                 List<Item> &fields, List<Item> &values, COND *conds,
132
 
                 uint32_t order_num, Order *order,
 
156
                 uint32_t order_num, order_st *order,
133
157
                 ha_rows limit, enum enum_duplicates,
134
158
                 bool ignore)
135
159
{
136
160
  bool          using_limit= limit != HA_POS_ERROR;
137
 
  bool          used_key_is_modified;
138
 
  bool          transactional_table;
139
 
  int           error;
 
161
  bool          safe_update= test(session->options & OPTION_SAFE_UPDATES);
 
162
  bool          used_key_is_modified, transactional_table, will_batch;
 
163
  bool          can_compare_record;
 
164
  int           error, loc_error;
140
165
  uint          used_index= MAX_KEY, dup_key_found;
141
166
  bool          need_sort= true;
 
167
  uint32_t          table_count= 0;
142
168
  ha_rows       updated, found;
143
169
  key_map       old_covering_keys;
144
170
  Table         *table;
145
 
  optimizer::SqlSelect *select= NULL;
146
 
  ReadRecord    info;
 
171
  SQL_SELECT    *select;
 
172
  READ_RECORD   info;
147
173
  Select_Lex    *select_lex= &session->lex->select_lex;
 
174
  bool          need_reopen;
148
175
  uint64_t     id;
149
176
  List<Item> all_fields;
150
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
177
  Session::killed_state killed_status= Session::NOT_KILLED;
151
178
 
152
 
  DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
153
 
  if (session->openTablesLock(table_list))
 
179
  for ( ; ; )
154
180
  {
155
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
156
 
    return 1;
 
181
    if (open_tables(session, &table_list, &table_count, 0))
 
182
      return(1);
 
183
 
 
184
    if (!lock_tables(session, table_list, table_count, &need_reopen))
 
185
      break;
 
186
    if (!need_reopen)
 
187
      return(1);
 
188
    close_tables_for_reopen(session, &table_list);
157
189
  }
158
190
 
 
191
  if (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
 
192
      (session->fill_derived_tables() &&
 
193
       mysql_handle_derived(session->lex, &mysql_derived_filling)))
 
194
    return(1);
 
195
 
 
196
  DRIZZLE_UPDATE_START();
159
197
  session->set_proc_info("init");
160
198
  table= table_list->table;
161
199
 
162
200
  /* Calculate "table->covering_keys" based on the WHERE */
163
 
  table->covering_keys= table->getShare()->keys_in_use;
 
201
  table->covering_keys= table->s->keys_in_use;
164
202
  table->quick_keys.reset();
165
203
 
166
204
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
167
 
  {
168
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
169
 
    return 1;
170
 
  }
 
205
    goto abort;
171
206
 
172
207
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
173
208
  /* Check the fields we are going to modify */
174
209
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
175
 
  {
176
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
177
 
    return 1;
178
 
  }
179
 
 
 
210
    goto abort;                               /* purecov: inspected */
180
211
  if (table->timestamp_field)
181
212
  {
182
213
    // Don't set timestamp column if this is modified
183
214
    if (table->timestamp_field->isWriteSet())
184
 
    {
185
215
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
186
 
    }
187
216
    else
188
217
    {
189
218
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
190
219
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
191
 
      {
192
 
        table->setWriteSet(table->timestamp_field->position());
193
 
      }
 
220
        table->setWriteSet(table->timestamp_field->field_index);
194
221
    }
195
222
  }
196
223
 
197
224
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
198
225
  {
199
226
    free_underlaid_joins(session, select_lex);
200
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
201
 
 
202
 
    return 1;
 
227
    goto abort;                               /* purecov: inspected */
203
228
  }
204
229
 
205
230
  if (select_lex->inner_refs_list.elements &&
206
231
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
207
232
  {
208
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
209
 
    return -1;
 
233
    DRIZZLE_UPDATE_END();
 
234
    return(-1);
210
235
  }
211
236
 
212
237
  if (conds)
222
247
    update force the table handler to retrieve write-only fields to be able
223
248
    to compare records and detect data change.
224
249
  */
225
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
250
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
226
251
      table->timestamp_field &&
227
252
      (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
228
253
       table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
229
 
  {
230
 
    *table->read_set|= *table->write_set;
231
 
  }
 
254
    bitmap_union(table->read_set, table->write_set);
232
255
  // Don't count on usage of 'only index' when calculating which key to use
233
256
  table->covering_keys.reset();
234
257
 
235
 
  /* Update the table->cursor->stats.records number */
236
 
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
258
  /* Update the table->file->stats.records number */
 
259
  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
237
260
 
238
 
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
 
261
  select= make_select(table, 0, 0, conds, 0, &error);
239
262
  if (error || !limit ||
240
 
      (select && select->check_quick(session, false, limit)))
 
263
      (select && select->check_quick(session, safe_update, limit)))
241
264
  {
242
265
    delete select;
243
 
    /**
244
 
     * Resetting the Diagnostic area to prevent
245
 
     * lp bug# 439719
246
 
     */
247
 
    session->main_da.reset_diagnostics_area();
248
266
    free_underlaid_joins(session, select_lex);
249
267
    if (error)
250
 
    {
251
 
      DRIZZLE_UPDATE_DONE(1, 0, 0);
252
 
      return 1;
253
 
    }
254
 
    DRIZZLE_UPDATE_DONE(0, 0, 0);
 
268
      goto abort;                               // Error in where
 
269
    DRIZZLE_UPDATE_END();
255
270
    session->my_ok();                           // No matching records
256
 
    return 0;
 
271
    return(0);
257
272
  }
258
273
  if (!select && limit != HA_POS_ERROR)
259
274
  {
260
 
    if ((used_index= optimizer::get_index_for_order(table, order, limit)) != MAX_KEY)
 
275
    if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY)
261
276
      need_sort= false;
262
277
  }
263
278
  /* If running in safe sql mode, don't allow updates without keys */
264
279
  if (table->quick_keys.none())
265
280
  {
266
281
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
282
    if (safe_update && !using_limit)
 
283
    {
 
284
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
285
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
286
      goto err;
 
287
    }
267
288
  }
268
289
 
269
290
  table->mark_columns_needed_for_update();
274
295
  {
275
296
    used_index= select->quick->index;
276
297
    used_key_is_modified= (!select->quick->unique_key_range() &&
277
 
                          select->quick->is_keys_used(*table->write_set));
 
298
                          select->quick->is_keys_used(table->write_set));
278
299
  }
279
300
  else
280
301
  {
281
302
    used_key_is_modified= 0;
282
303
    if (used_index == MAX_KEY)                  // no index for sort order
283
 
      used_index= table->cursor->key_used_on_scan;
 
304
      used_index= table->file->key_used_on_scan;
284
305
    if (used_index != MAX_KEY)
285
 
      used_key_is_modified= is_key_used(table, used_index, *table->write_set);
 
306
      used_key_is_modified= is_key_used(table, used_index, table->write_set);
286
307
  }
287
308
 
288
309
 
311
332
        NOTE: filesort will call table->prepare_for_position()
312
333
      */
313
334
      uint32_t         length= 0;
314
 
      SortField  *sortorder;
 
335
      SORT_FIELD  *sortorder;
315
336
      ha_rows examined_rows;
316
 
      FileSort filesort(*session);
317
337
 
318
 
      table->sort.io_cache= new internal::IO_CACHE;
 
338
      table->sort.io_cache = new IO_CACHE;
 
339
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
319
340
 
320
341
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
321
 
          (table->sort.found_records= filesort.run(table, sortorder, length,
322
 
                                                   select, limit, 1,
323
 
                                                   examined_rows)) == HA_POS_ERROR)
 
342
          (table->sort.found_records= filesort(session, table, sortorder, length,
 
343
                                               select, limit, 1,
 
344
                                               &examined_rows))
 
345
          == HA_POS_ERROR)
324
346
      {
325
347
        goto err;
326
348
      }
339
361
        update these in a separate loop based on the pointer.
340
362
      */
341
363
 
342
 
      internal::IO_CACHE tempfile;
343
 
      if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
344
 
      {
 
364
      IO_CACHE tempfile;
 
365
      if (open_cached_file(&tempfile, drizzle_tmpdir,TEMP_PREFIX,
 
366
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
345
367
        goto err;
346
 
      }
347
368
 
348
369
      /* If quick select is used, initialize it before retrieving rows. */
349
370
      if (select && select->quick && select->quick->reset())
350
371
        goto err;
351
 
      table->cursor->try_semi_consistent_read(1);
 
372
      table->file->try_semi_consistent_read(1);
352
373
 
353
374
      /*
354
375
        When we get here, we have one of the following options:
362
383
      */
363
384
 
364
385
      if (used_index == MAX_KEY || (select && select->quick))
365
 
      {
366
 
        info.init_read_record(session, table, select, 0, true);
367
 
      }
 
386
        init_read_record(&info,session,table,select,0,1);
368
387
      else
369
 
      {
370
 
        info.init_read_record_idx(session, table, 1, used_index);
371
 
      }
 
388
        init_read_record_idx(&info, session, table, 1, used_index);
372
389
 
373
390
      session->set_proc_info("Searching rows for update");
374
391
      ha_rows tmp_limit= limit;
375
392
 
376
 
      while (not(error= info.read_record(&info)) && not session->getKilled())
 
393
      while (!(error=info.read_record(&info)) && !session->killed)
377
394
      {
378
395
        if (!(select && select->skip_record()))
379
396
        {
380
 
          if (table->cursor->was_semi_consistent_read())
 
397
          if (table->file->was_semi_consistent_read())
381
398
            continue;  /* repeat the read of the same row if it still exists */
382
399
 
383
 
          table->cursor->position(table->getInsertRecord());
384
 
          if (my_b_write(&tempfile,table->cursor->ref,
385
 
                         table->cursor->ref_length))
 
400
          table->file->position(table->record[0]);
 
401
          if (my_b_write(&tempfile,table->file->ref,
 
402
                         table->file->ref_length))
386
403
          {
387
 
            error=1;
388
 
            break;
 
404
            error=1; /* purecov: inspected */
 
405
            break; /* purecov: inspected */
389
406
          }
390
407
          if (!--limit && using_limit)
391
408
          {
394
411
          }
395
412
        }
396
413
        else
397
 
          table->cursor->unlock_row();
 
414
          table->file->unlock_row();
398
415
      }
399
 
      if (session->getKilled() && not error)
 
416
      if (session->killed && !error)
400
417
        error= 1;                               // Aborted
401
418
      limit= tmp_limit;
402
 
      table->cursor->try_semi_consistent_read(0);
403
 
      info.end_read_record();
 
419
      table->file->try_semi_consistent_read(0);
 
420
      end_read_record(&info);
404
421
 
405
422
      /* Change select to use tempfile */
406
423
      if (select)
413
430
      }
414
431
      else
415
432
      {
416
 
        select= new optimizer::SqlSelect;
 
433
        select= new SQL_SELECT;
417
434
        select->head=table;
418
435
      }
419
 
      if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
420
 
        error=1;
421
 
      // Read row ptrs from this cursor
422
 
      memcpy(select->file, &tempfile, sizeof(tempfile));
 
436
      if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
 
437
        error=1; /* purecov: inspected */
 
438
      select->file=tempfile;                    // Read row ptrs from this file
423
439
      if (error >= 0)
424
440
        goto err;
425
441
    }
428
444
  }
429
445
 
430
446
  if (ignore)
431
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
447
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
432
448
 
433
449
  if (select && select->quick && select->quick->reset())
434
450
    goto err;
435
 
  table->cursor->try_semi_consistent_read(1);
436
 
  info.init_read_record(session, table, select, 0, true);
 
451
  table->file->try_semi_consistent_read(1);
 
452
  init_read_record(&info,session,table,select,0,1);
437
453
 
438
454
  updated= found= 0;
439
455
  /*
448
464
  session->cuted_fields= 0L;
449
465
  session->set_proc_info("Updating");
450
466
 
451
 
  transactional_table= table->cursor->has_transactions();
 
467
  transactional_table= table->file->has_transactions();
452
468
  session->abort_on_warning= test(!ignore);
 
469
  will_batch= !table->file->start_bulk_update();
453
470
 
454
471
  /*
455
472
    Assure that we can use position()
456
473
    if we need to create an error message.
457
474
  */
458
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
 
475
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
459
476
    table->prepare_for_position();
460
477
 
461
 
  while (not (error=info.read_record(&info)) && not session->getKilled())
 
478
  /*
 
479
    We can use compare_record() to optimize away updates if
 
480
    the table handler is returning all columns OR if
 
481
    if all updated columns are read
 
482
  */
 
483
  can_compare_record= (!(table->file->ha_table_flags() &
 
484
                         HA_PARTIAL_COLUMN_READ) ||
 
485
                       bitmap_is_subset(table->write_set, table->read_set));
 
486
 
 
487
  while (!(error=info.read_record(&info)) && !session->killed)
462
488
  {
463
 
    if (not (select && select->skip_record()))
 
489
    if (!(select && select->skip_record()))
464
490
    {
465
 
      if (table->cursor->was_semi_consistent_read())
 
491
      if (table->file->was_semi_consistent_read())
466
492
        continue;  /* repeat the read of the same row if it still exists */
467
493
 
468
494
      table->storeRecord();
469
 
      if (fill_record(session, fields, values))
470
 
        break;
 
495
      if (fill_record(session, fields, values, 0))
 
496
        break; /* purecov: inspected */
471
497
 
472
498
      found++;
473
499
 
474
 
      if (! table->records_are_comparable() || table->compare_records())
 
500
      if (!can_compare_record || table->compare_record())
475
501
      {
476
 
        /* Non-batched update */
477
 
        error= table->cursor->updateRecord(table->getUpdateRecord(),
478
 
                                            table->getInsertRecord());
479
 
 
480
 
        table->auto_increment_field_not_null= false;
481
 
 
 
502
        if (will_batch)
 
503
        {
 
504
          /*
 
505
            Typically a batched handler can execute the batched jobs when:
 
506
            1) When specifically told to do so
 
507
            2) When it is not a good idea to batch anymore
 
508
            3) When it is necessary to send batch for other reasons
 
509
               (One such reason is when READ's must be performed)
 
510
 
 
511
            1) is covered by exec_bulk_update calls.
 
512
            2) and 3) is handled by the bulk_update_row method.
 
513
 
 
514
            bulk_update_row can execute the updates including the one
 
515
            defined in the bulk_update_row or not including the row
 
516
            in the call. This is up to the handler implementation and can
 
517
            vary from call to call.
 
518
 
 
519
            The dup_key_found reports the number of duplicate keys found
 
520
            in those updates actually executed. It only reports those if
 
521
            the extra call with HA_EXTRA_IGNORE_DUP_KEY have been issued.
 
522
            If this hasn't been issued it returns an error code and can
 
523
            ignore this number. Thus any handler that implements batching
 
524
            for UPDATE IGNORE must also handle this extra call properly.
 
525
 
 
526
            If a duplicate key is found on the record included in this
 
527
            call then it should be included in the count of dup_key_found
 
528
            and error should be set to 0 (only if these errors are ignored).
 
529
          */
 
530
          error= table->file->ha_bulk_update_row(table->record[1],
 
531
                                                 table->record[0],
 
532
                                                 &dup_key_found);
 
533
          limit+= dup_key_found;
 
534
          updated-= dup_key_found;
 
535
        }
 
536
        else
 
537
        {
 
538
          /* Non-batched update */
 
539
          error= table->file->ha_update_row(table->record[1],
 
540
                                            table->record[0]);
 
541
        }
482
542
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
483
 
        {
 
543
        {
484
544
          if (error != HA_ERR_RECORD_IS_THE_SAME)
485
545
            updated++;
486
546
          else
487
547
            error= 0;
488
 
        }
489
 
        else if (! ignore ||
490
 
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
491
 
        {
 
548
        }
 
549
        else if (!ignore ||
 
550
                 table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
551
        {
492
552
          /*
493
553
            If (ignore && error is ignorable) we don't have to
494
554
            do anything; otherwise...
495
555
          */
496
556
          myf flags= 0;
497
557
 
498
 
          if (table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
558
          if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
499
559
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
500
560
 
501
561
          prepare_record_for_error_message(error, table);
502
 
          table->print_error(error,MYF(flags));
503
 
          error= 1;
504
 
          break;
505
 
        }
 
562
          table->file->print_error(error,MYF(flags));
 
563
          error= 1;
 
564
          break;
 
565
        }
506
566
      }
507
567
 
508
568
      if (!--limit && using_limit)
509
569
      {
510
 
        error= -1;                              // Simulate end of cursor
511
 
        break;
 
570
        /*
 
571
          We have reached end-of-file in most common situations where no
 
572
          batching has occurred and if batching was supposed to occur but
 
573
          no updates were made and finally when the batch execution was
 
574
          performed without error and without finding any duplicate keys.
 
575
          If the batched updates were performed with errors we need to
 
576
          check and if no error but duplicate key's found we need to
 
577
          continue since those are not counted for in limit.
 
578
        */
 
579
        if (will_batch &&
 
580
            ((error= table->file->exec_bulk_update(&dup_key_found)) ||
 
581
             dup_key_found))
 
582
        {
 
583
          if (error)
 
584
          {
 
585
            /* purecov: begin inspected */
 
586
            /*
 
587
              The handler should not report error of duplicate keys if they
 
588
              are ignored. This is a requirement on batching handlers.
 
589
            */
 
590
            prepare_record_for_error_message(error, table);
 
591
            table->file->print_error(error,MYF(0));
 
592
            error= 1;
 
593
            break;
 
594
            /* purecov: end */
 
595
          }
 
596
          /*
 
597
            Either an error was found and we are ignoring errors or there
 
598
            were duplicate keys found. In both cases we need to correct
 
599
            the counters and continue the loop.
 
600
          */
 
601
          limit= dup_key_found; //limit is 0 when we get here so need to +
 
602
          updated-= dup_key_found;
 
603
        }
 
604
        else
 
605
        {
 
606
          error= -1;                            // Simulate end of file
 
607
          break;
 
608
        }
512
609
      }
513
610
    }
514
611
    else
515
 
      table->cursor->unlock_row();
 
612
      table->file->unlock_row();
516
613
    session->row_count++;
517
614
  }
518
615
  dup_key_found= 0;
524
621
    It's assumed that if an error was set in combination with an effective
525
622
    killed status then the error is due to killing.
526
623
  */
527
 
  killed_status= session->getKilled(); // get the status of the volatile
 
624
  killed_status= session->killed; // get the status of the volatile
528
625
  // simulated killing after the loop must be ineffective for binlogging
529
626
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
530
627
 
531
 
  updated-= dup_key_found;
532
 
  table->cursor->try_semi_consistent_read(0);
 
628
  if (error &&
 
629
      will_batch &&
 
630
      (loc_error= table->file->exec_bulk_update(&dup_key_found)))
 
631
    /*
 
632
      An error has occurred when a batched update was performed and returned
 
633
      an error indication. It cannot be an allowed duplicate key error since
 
634
      we require the batching handler to treat this as a normal behavior.
 
635
 
 
636
      Otherwise we simply remove the number of duplicate keys records found
 
637
      in the batched update.
 
638
    */
 
639
  {
 
640
    /* purecov: begin inspected */
 
641
    prepare_record_for_error_message(loc_error, table);
 
642
    table->file->print_error(loc_error,MYF(ME_FATALERROR));
 
643
    error= 1;
 
644
    /* purecov: end */
 
645
  }
 
646
  else
 
647
    updated-= dup_key_found;
 
648
  if (will_batch)
 
649
    table->file->end_bulk_update();
 
650
  table->file->try_semi_consistent_read(0);
533
651
 
534
652
  if (!transactional_table && updated > 0)
535
 
    session->transaction.stmt.markModifiedNonTransData();
 
653
    session->transaction.stmt.modified_non_trans_table= true;
536
654
 
537
 
  info.end_read_record();
 
655
  end_read_record(&info);
538
656
  delete select;
539
657
  session->set_proc_info("end");
540
 
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
658
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
541
659
 
542
660
  /*
543
661
    error < 0 means really no error at all: we processed all rows until the
544
662
    last one without error. error > 0 means an error (e.g. unique key
545
663
    violation and no IGNORE or REPLACE). error == 0 is also an error (if
546
664
    preparing the record or invoking before triggers fails). See
547
 
    autocommitOrRollback(error>=0) and return(error>=0) below.
 
665
    ha_autocommit_or_rollback(error>=0) and return(error>=0) below.
548
666
    Sometimes we want to binlog even if we updated no rows, in case user used
549
667
    it to be sure master and slave are in same state.
550
668
  */
551
 
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
 
669
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
552
670
  {
553
 
    if (session->transaction.stmt.hasModifiedNonTransData())
554
 
      session->transaction.all.markModifiedNonTransData();
 
671
    if (session->transaction.stmt.modified_non_trans_table)
 
672
      session->transaction.all.modified_non_trans_table= true;
555
673
  }
556
 
  assert(transactional_table || !updated || session->transaction.stmt.hasModifiedNonTransData());
 
674
  assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
557
675
  free_underlaid_joins(session, select_lex);
558
676
 
559
677
  /* If LAST_INSERT_ID(X) was used, report X */
560
678
  id= session->arg_of_last_insert_id_function ?
561
679
    session->first_successful_insert_id_in_prev_stmt : 0;
562
680
 
 
681
  DRIZZLE_UPDATE_END();
563
682
  if (error < 0)
564
683
  {
565
684
    char buff[STRING_BUFFER_USUAL_SIZE];
566
 
    snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
 
685
    sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
567
686
            (ulong) session->cuted_fields);
568
 
    session->row_count_func= updated;
569
 
    /**
570
 
     * Resetting the Diagnostic area to prevent
571
 
     * lp bug# 439719
572
 
     */
573
 
    session->main_da.reset_diagnostics_area();
574
 
    session->my_ok((ulong) session->row_count_func, found, id, buff);
575
 
    session->status_var.updated_row_count+= session->row_count_func;
 
687
    session->row_count_func=
 
688
      (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
689
    session->my_ok((ulong) session->row_count_func, id, buff);
576
690
  }
577
 
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;              /* calc cuted fields */
 
691
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              /* calc cuted fields */
578
692
  session->abort_on_warning= 0;
579
 
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
580
 
  return ((error >= 0 || session->is_error()) ? 1 : 0);
 
693
  return((error >= 0 || session->is_error()) ? 1 : 0);
581
694
 
582
695
err:
583
696
  delete select;
585
698
  if (table->key_read)
586
699
  {
587
700
    table->key_read=0;
588
 
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
701
    table->file->extra(HA_EXTRA_NO_KEYREAD);
589
702
  }
590
703
  session->abort_on_warning= 0;
591
704
 
592
 
  DRIZZLE_UPDATE_DONE(1, 0, 0);
593
 
  return 1;
 
705
abort:
 
706
  DRIZZLE_UPDATE_END();
 
707
  return(1);
594
708
}
595
709
 
596
710
/*
601
715
    session                     - thread handler
602
716
    table_list          - global/local table list
603
717
    conds               - conditions
604
 
    order_num           - number of ORDER BY list entries
605
 
    order               - ORDER BY clause list
 
718
    order_num           - number of order_st BY list entries
 
719
    order               - order_st BY clause list
606
720
 
607
721
  RETURN VALUE
608
722
    false OK
609
723
    true  error
610
724
*/
611
725
bool mysql_prepare_update(Session *session, TableList *table_list,
612
 
                         Item **conds, uint32_t order_num, Order *order)
 
726
                         Item **conds, uint32_t order_num, order_st *order)
613
727
{
614
728
  List<Item> all_fields;
615
729
  Select_Lex *select_lex= &session->lex->select_lex;
621
735
                                    table_list,
622
736
                                    &select_lex->leaf_tables,
623
737
                                    false) ||
624
 
      session->setup_conds(table_list, conds) ||
 
738
      setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
625
739
      select_lex->setup_ref_array(session, order_num) ||
626
740
      setup_order(session, select_lex->ref_pointer_array,
627
741
                  table_list, all_fields, all_fields, order))
630
744
  /* Check that we are not using table that we are updating in a sub select */
631
745
  {
632
746
    TableList *duplicate;
633
 
    if ((duplicate= unique_table(table_list, table_list->next_global)))
634
 
    {
635
 
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
636
 
      return true;
637
 
    }
638
 
  }
639
 
 
640
 
  return false;
641
 
}
642
 
 
643
 
} /* namespace drizzled */
 
747
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
 
748
    {
 
749
      update_non_unique_table_error(table_list, "UPDATE", duplicate);
 
750
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
 
751
      return true;
 
752
    }
 
753
  }
 
754
 
 
755
  return false;
 
756
}
 
757
 
 
758
 
 
759
/***************************************************************************
 
760
  Update multiple tables from join
 
761
***************************************************************************/
 
762
 
 
763
/*
 
764
  Get table map for list of Item_field
 
765
*/
 
766
 
 
767
static table_map get_table_map(List<Item> *items)
 
768
{
 
769
  List_iterator_fast<Item> item_it(*items);
 
770
  Item_field *item;
 
771
  table_map map= 0;
 
772
 
 
773
  while ((item= (Item_field *) item_it++))
 
774
    map|= item->used_tables();
 
775
  return map;
 
776
}
 
777
 
 
778
 
 
779
/*
 
780
  make update specific preparation and checks after opening tables
 
781
 
 
782
  SYNOPSIS
 
783
    mysql_multi_update_prepare()
 
784
    session         thread handler
 
785
 
 
786
  RETURN
 
787
    false OK
 
788
    true  Error
 
789
*/
 
790
 
 
791
int mysql_multi_update_prepare(Session *session)
 
792
{
 
793
  LEX *lex= session->lex;
 
794
  TableList *table_list= lex->query_tables;
 
795
  TableList *tl, *leaves;
 
796
  List<Item> *fields= &lex->select_lex.item_list;
 
797
  table_map tables_for_update;
 
798
  bool update_view= 0;
 
799
  /*
 
800
    if this multi-update was converted from usual update, here is table
 
801
    counter else junk will be assigned here, but then replaced with real
 
802
    count in open_tables()
 
803
  */
 
804
  uint32_t  table_count= lex->table_count;
 
805
  const bool using_lock_tables= session->locked_tables != 0;
 
806
  bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
 
807
  bool need_reopen= false;
 
808
 
 
809
 
 
810
  /* following need for prepared statements, to run next time multi-update */
 
811
  session->lex->sql_command= SQLCOM_UPDATE_MULTI;
 
812
 
 
813
reopen_tables:
 
814
 
 
815
  /* open tables and create derived ones, but do not lock and fill them */
 
816
  if (((original_multiupdate || need_reopen) &&
 
817
       open_tables(session, &table_list, &table_count, 0)) ||
 
818
      mysql_handle_derived(lex, &mysql_derived_prepare))
 
819
    return true;
 
820
  /*
 
821
    setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
 
822
    second time, but this call will do nothing (there are check for second
 
823
    call in setup_tables()).
 
824
  */
 
825
 
 
826
  if (setup_tables_and_check_access(session, &lex->select_lex.context,
 
827
                                    &lex->select_lex.top_join_list,
 
828
                                    table_list,
 
829
                                    &lex->select_lex.leaf_tables, false))
 
830
    return true;
 
831
 
 
832
  if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
 
833
    return true;
 
834
 
 
835
  if (update_view && check_fields(session, *fields))
 
836
  {
 
837
    return true;
 
838
  }
 
839
 
 
840
  tables_for_update= get_table_map(fields);
 
841
 
 
842
  /*
 
843
    Setup timestamp handling and locking mode
 
844
  */
 
845
  leaves= lex->select_lex.leaf_tables;
 
846
  for (tl= leaves; tl; tl= tl->next_leaf)
 
847
  {
 
848
    Table *table= tl->table;
 
849
    /* Only set timestamp column if this is not modified */
 
850
    if (table->timestamp_field && table->timestamp_field->isWriteSet())
 
851
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
852
 
 
853
    /* if table will be updated then check that it is unique */
 
854
    if (table->map & tables_for_update)
 
855
    {
 
856
      table->mark_columns_needed_for_update();
 
857
      /*
 
858
        If table will be updated we should not downgrade lock for it and
 
859
        leave it as is.
 
860
      */
 
861
    }
 
862
    else
 
863
    {
 
864
      /*
 
865
        If we are using the binary log, we need TL_READ_NO_INSERT to get
 
866
        correct order of statements. Otherwise, we use a TL_READ lock to
 
867
        improve performance.
 
868
      */
 
869
      tl->lock_type= TL_READ;
 
870
      tl->updating= 0;
 
871
      /* Update Table::lock_type accordingly. */
 
872
      if (!tl->placeholder() && !using_lock_tables)
 
873
        tl->table->reginfo.lock_type= tl->lock_type;
 
874
    }
 
875
  }
 
876
 
 
877
  /* now lock and fill tables */
 
878
  if (lock_tables(session, table_list, table_count, &need_reopen))
 
879
  {
 
880
    if (!need_reopen)
 
881
      return true;
 
882
 
 
883
    /*
 
884
      We have to reopen tables since some of them were altered or dropped
 
885
      during lock_tables() or something was done with their triggers.
 
886
      Let us do some cleanups to be able do setup_table() and setup_fields()
 
887
      once again.
 
888
    */
 
889
    List_iterator_fast<Item> it(*fields);
 
890
    Item *item;
 
891
    while ((item= it++))
 
892
      item->cleanup();
 
893
 
 
894
    close_tables_for_reopen(session, &table_list);
 
895
    goto reopen_tables;
 
896
  }
 
897
 
 
898
  /*
 
899
    Check that we are not using table that we are updating, but we should
 
900
    skip all tables of UPDATE SELECT itself
 
901
  */
 
902
  lex->select_lex.exclude_from_table_unique_test= true;
 
903
  /* We only need SELECT privilege for columns in the values list */
 
904
  for (tl= leaves; tl; tl= tl->next_leaf)
 
905
  {
 
906
    if (tl->lock_type != TL_READ &&
 
907
        tl->lock_type != TL_READ_NO_INSERT)
 
908
    {
 
909
      TableList *duplicate;
 
910
      if ((duplicate= unique_table(session, tl, table_list, 0)))
 
911
      {
 
912
        update_non_unique_table_error(table_list, "UPDATE", duplicate);
 
913
        return true;
 
914
      }
 
915
    }
 
916
  }
 
917
  /*
 
918
    Set exclude_from_table_unique_test value back to false. It is needed for
 
919
    further check in multi_update::prepare whether to use record cache.
 
920
  */
 
921
  lex->select_lex.exclude_from_table_unique_test= false;
 
922
 
 
923
  if (session->fill_derived_tables() &&
 
924
      mysql_handle_derived(lex, &mysql_derived_filling))
 
925
    return true;
 
926
 
 
927
  return (false);
 
928
}
 
929
 
 
930
 
 
931
/*
 
932
  Setup multi-update handling and call SELECT to do the join
 
933
*/
 
934
 
 
935
bool mysql_multi_update(Session *session,
 
936
                        TableList *table_list,
 
937
                        List<Item> *fields,
 
938
                        List<Item> *values,
 
939
                        COND *conds,
 
940
                        uint64_t options,
 
941
                        enum enum_duplicates handle_duplicates, bool ignore,
 
942
                        Select_Lex_Unit *unit, Select_Lex *select_lex)
 
943
{
 
944
  multi_update *result;
 
945
  bool res;
 
946
 
 
947
  if (!(result= new multi_update(table_list,
 
948
                                 session->lex->select_lex.leaf_tables,
 
949
                                 fields, values,
 
950
                                 handle_duplicates, ignore)))
 
951
    return true;
 
952
 
 
953
  session->abort_on_warning= true;
 
954
 
 
955
  List<Item> total_list;
 
956
  res= mysql_select(session, &select_lex->ref_pointer_array,
 
957
                      table_list, select_lex->with_wild,
 
958
                      total_list,
 
959
                      conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
 
960
                      options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
 
961
                      OPTION_SETUP_TABLES_DONE,
 
962
                      result, unit, select_lex);
 
963
  res|= session->is_error();
 
964
  if (unlikely(res))
 
965
  {
 
966
    /* If we had a another error reported earlier then this will be ignored */
 
967
    result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
 
968
    result->abort();
 
969
  }
 
970
  delete result;
 
971
  session->abort_on_warning= 0;
 
972
  return false;
 
973
}
 
974
 
 
975
 
 
976
multi_update::multi_update(TableList *table_list,
 
977
                           TableList *leaves_list,
 
978
                           List<Item> *field_list, List<Item> *value_list,
 
979
                           enum enum_duplicates handle_duplicates_arg,
 
980
                           bool ignore_arg)
 
981
  :all_tables(table_list), leaves(leaves_list),
 
982
   tmp_tables(0), updated(0), found(0), fields(field_list),
 
983
   values(value_list), table_count(0), copy_field(0),
 
984
   handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
 
985
   transactional_tables(0), ignore(ignore_arg), error_handled(0)
 
986
{}
 
987
 
 
988
 
 
989
/*
 
990
  Connect fields with tables and create list of tables that are updated
 
991
*/
 
992
 
 
993
int multi_update::prepare(List<Item> &,
 
994
                          Select_Lex_Unit *)
 
995
{
 
996
  TableList *table_ref;
 
997
  table_map tables_to_update;
 
998
  Item_field *item;
 
999
  List_iterator_fast<Item> field_it(*fields);
 
1000
  List_iterator_fast<Item> value_it(*values);
 
1001
  uint32_t i, max_fields;
 
1002
  uint32_t leaf_table_count= 0;
 
1003
 
 
1004
  session->count_cuted_fields= CHECK_FIELD_WARN;
 
1005
  session->cuted_fields=0L;
 
1006
  session->set_proc_info("updating main table");
 
1007
 
 
1008
  tables_to_update= get_table_map(fields);
 
1009
 
 
1010
  if (!tables_to_update)
 
1011
  {
 
1012
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
 
1013
    return(1);
 
1014
  }
 
1015
 
 
1016
  /*
 
1017
    We have to check values after setup_tables to get covering_keys right in
 
1018
    reference tables
 
1019
  */
 
1020
 
 
1021
  if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
 
1022
    return(1);
 
1023
 
 
1024
  /*
 
1025
    Save tables beeing updated in update_tables
 
1026
    update_table->shared is position for table
 
1027
    Don't use key read on tables that are updated
 
1028
  */
 
1029
  for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
 
1030
  {
 
1031
    /* TODO: add support of view of join support */
 
1032
    Table *table=table_ref->table;
 
1033
    leaf_table_count++;
 
1034
    if (tables_to_update & table->map)
 
1035
    {
 
1036
      TableList *tl= (TableList*) session->memdup((char*) table_ref,
 
1037
                                                sizeof(*tl));
 
1038
      if (!tl)
 
1039
        return(1);
 
1040
      update_tables.push_back(tl);
 
1041
      tl->shared= table_count++;
 
1042
      table->no_keyread=1;
 
1043
      table->covering_keys.reset();
 
1044
      table->pos_in_table_list= tl;
 
1045
    }
 
1046
  }
 
1047
 
 
1048
 
 
1049
  table_count=  update_tables.size();
 
1050
 
 
1051
  tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
 
1052
  tmp_table_param = (Tmp_Table_Param*) session->calloc(sizeof(Tmp_Table_Param) *
 
1053
                                                   table_count);
 
1054
  fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
 
1055
                                              table_count);
 
1056
  values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
 
1057
                                              table_count);
 
1058
  if (session->is_fatal_error)
 
1059
    return(1);
 
1060
  for (i=0 ; i < table_count ; i++)
 
1061
  {
 
1062
    fields_for_table[i]= new List_item;
 
1063
    values_for_table[i]= new List_item;
 
1064
  }
 
1065
  if (session->is_fatal_error)
 
1066
    return(1);
 
1067
 
 
1068
  /* Split fields into fields_for_table[] and values_by_table[] */
 
1069
 
 
1070
  while ((item= (Item_field *) field_it++))
 
1071
  {
 
1072
    Item *value= value_it++;
 
1073
    uint32_t offset= item->field->table->pos_in_table_list->shared;
 
1074
    fields_for_table[offset]->push_back(item);
 
1075
    values_for_table[offset]->push_back(value);
 
1076
  }
 
1077
  if (session->is_fatal_error)
 
1078
    return(1);
 
1079
 
 
1080
  /* Allocate copy fields */
 
1081
  max_fields=0;
 
1082
  for (i=0 ; i < table_count ; i++)
 
1083
    set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
 
1084
  copy_field= new Copy_field[max_fields];
 
1085
  return(session->is_fatal_error != 0);
 
1086
}
 
1087
 
 
1088
 
 
1089
/*
 
1090
  Check if table is safe to update on fly
 
1091
 
 
1092
  SYNOPSIS
 
1093
    safe_update_on_fly()
 
1094
    session                 Thread handler
 
1095
    join_tab            How table is used in join
 
1096
    all_tables          List of tables
 
1097
 
 
1098
  NOTES
 
1099
    We can update the first table in join on the fly if we know that
 
1100
    a row in this table will never be read twice. This is true under
 
1101
    the following conditions:
 
1102
 
 
1103
    - We are doing a table scan and the data is in a separate file (MyISAM) or
 
1104
      if we don't update a clustered key.
 
1105
 
 
1106
    - We are doing a range scan and we don't update the scan key or
 
1107
      the primary key for a clustered table handler.
 
1108
 
 
1109
    - Table is not joined to itself.
 
1110
 
 
1111
    This function gets information about fields to be updated from
 
1112
    the Table::write_set bitmap.
 
1113
 
 
1114
  WARNING
 
1115
    This code is a bit dependent of how make_join_readinfo() works.
 
1116
 
 
1117
  RETURN
 
1118
    0           Not safe to update
 
1119
    1           Safe to update
 
1120
*/
 
1121
 
 
1122
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
 
1123
                               TableList *table_ref, TableList *all_tables)
 
1124
{
 
1125
  Table *table= join_tab->table;
 
1126
  if (unique_table(session, table_ref, all_tables, 0))
 
1127
    return 0;
 
1128
  switch (join_tab->type) {
 
1129
  case JT_SYSTEM:
 
1130
  case JT_CONST:
 
1131
  case JT_EQ_REF:
 
1132
    return true;                                // At most one matching row
 
1133
  case JT_REF:
 
1134
  case JT_REF_OR_NULL:
 
1135
    return !is_key_used(table, join_tab->ref.key, table->write_set);
 
1136
  case JT_ALL:
 
1137
    /* If range search on index */
 
1138
    if (join_tab->quick)
 
1139
      return !join_tab->quick->is_keys_used(table->write_set);
 
1140
    /* If scanning in clustered key */
 
1141
    if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
1142
        table->s->primary_key < MAX_KEY)
 
1143
      return !is_key_used(table, table->s->primary_key, table->write_set);
 
1144
    return true;
 
1145
  default:
 
1146
    break;                                      // Avoid compler warning
 
1147
  }
 
1148
  return false;
 
1149
 
 
1150
}
 
1151
 
 
1152
 
 
1153
/*
 
1154
  Initialize table for multi table
 
1155
 
 
1156
  IMPLEMENTATION
 
1157
    - Update first table in join on the fly, if possible
 
1158
    - Create temporary tables to store changed values for all other tables
 
1159
      that are updated (and main_table if the above doesn't hold).
 
1160
*/
 
1161
 
 
1162
bool
 
1163
multi_update::initialize_tables(JOIN *join)
 
1164
{
 
1165
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
 
1166
    return(1);
 
1167
  main_table=join->join_tab->table;
 
1168
  table_to_update= 0;
 
1169
 
 
1170
  /* Any update has at least one pair (field, value) */
 
1171
  assert(fields->elements);
 
1172
 
 
1173
  /* Create a temporary table for keys to all tables, except main table */
 
1174
  for (list<TableList*>::iterator it= update_tables.begin(); 
 
1175
       it != update_tables.end(); 
 
1176
       ++it)
 
1177
  {
 
1178
    Table *table= (*it)->table;
 
1179
    uint32_t cnt= (*it)->shared;
 
1180
    List<Item> temp_fields;
 
1181
    order_st     group;
 
1182
    Tmp_Table_Param *tmp_param;
 
1183
 
 
1184
    table->mark_columns_needed_for_update();
 
1185
    if (ignore)
 
1186
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
1187
    if (table == main_table)                    // First table in join
 
1188
    {
 
1189
      if (safe_update_on_fly(session, join->join_tab, (*it), all_tables))
 
1190
      {
 
1191
        table_to_update= main_table;            // Update table on the fly
 
1192
        continue;
 
1193
      }
 
1194
    }
 
1195
    table->prepare_for_position();
 
1196
 
 
1197
    tmp_param= tmp_table_param+cnt;
 
1198
 
 
1199
    /*
 
1200
      Create a temporary table to store all fields that are changed for this
 
1201
      table. The first field in the temporary table is a pointer to the
 
1202
      original row so that we can find and update it. For the updatable
 
1203
      VIEW a few following fields are rowids of tables used in the CHECK
 
1204
      OPTION condition.
 
1205
    */
 
1206
 
 
1207
    List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
 
1208
    Table *tbl= table;
 
1209
    do
 
1210
    {
 
1211
      Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
 
1212
                                                  tbl->alias, tbl->s, &my_charset_bin);
 
1213
      if (!field)
 
1214
        return(1);
 
1215
      field->init(tbl);
 
1216
      /*
 
1217
        The field will be converted to varstring when creating tmp table if
 
1218
        table to be updated was created by mysql 4.1. Deny this.
 
1219
      */
 
1220
      Item_field *ifield= new Item_field((Field *) field);
 
1221
      if (!ifield)
 
1222
         return(1);
 
1223
      ifield->maybe_null= 0;
 
1224
      if (temp_fields.push_back(ifield))
 
1225
        return(1);
 
1226
    } while ((tbl= tbl_it++));
 
1227
 
 
1228
    temp_fields.concat(fields_for_table[cnt]);
 
1229
 
 
1230
    /* Make an unique key over the first field to avoid duplicated updates */
 
1231
    memset(&group, 0, sizeof(group));
 
1232
    group.asc= 1;
 
1233
    group.item= (Item**) temp_fields.head_ref();
 
1234
 
 
1235
    tmp_param->quick_group=1;
 
1236
    tmp_param->field_count=temp_fields.elements;
 
1237
    tmp_param->group_parts=1;
 
1238
    tmp_param->group_length= table->file->ref_length;
 
1239
    if (!(tmp_tables[cnt]=create_tmp_table(session,
 
1240
                                           tmp_param,
 
1241
                                           temp_fields,
 
1242
                                           (order_st*) &group, 0, 0,
 
1243
                                           TMP_TABLE_ALL_COLUMNS,
 
1244
                                           HA_POS_ERROR,
 
1245
                                           (char *) "")))
 
1246
      return(1);
 
1247
    tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
 
1248
  }
 
1249
  return(0);
 
1250
}
 
1251
 
 
1252
 
 
1253
multi_update::~multi_update()
 
1254
{
 
1255
  TableList *table;
 
1256
  for (list<TableList*>::iterator it= update_tables.begin(); 
 
1257
       it != update_tables.end(); 
 
1258
       ++it)
 
1259
  {
 
1260
    table= *it;
 
1261
    table->table->no_keyread= table->table->no_cache= 0;
 
1262
    if (ignore)
 
1263
      table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
1264
  }
 
1265
 
 
1266
  if (tmp_tables)
 
1267
  {
 
1268
    for (uint32_t cnt = 0; cnt < table_count; cnt++)
 
1269
    {
 
1270
      if (tmp_tables[cnt])
 
1271
      {
 
1272
        tmp_tables[cnt]->free_tmp_table(session);
 
1273
        tmp_table_param[cnt].cleanup();
 
1274
      }
 
1275
    }
 
1276
  }
 
1277
  if (copy_field)
 
1278
    delete [] copy_field;
 
1279
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              // Restore this setting
 
1280
  assert(trans_safe || !updated ||
 
1281
              session->transaction.all.modified_non_trans_table);
 
1282
}
 
1283
 
 
1284
 
 
1285
bool multi_update::send_data(List<Item> &)
 
1286
{
 
1287
  for (list<TableList*>::iterator it= update_tables.begin(); 
 
1288
       it != update_tables.end(); 
 
1289
       ++it)
 
1290
  {
 
1291
    Table *table= (*it)->table;
 
1292
    uint32_t offset= (*it)->shared;
 
1293
    /*
 
1294
      Check if we are using outer join and we didn't find the row
 
1295
      or if we have already updated this row in the previous call to this
 
1296
      function.
 
1297
 
 
1298
      The same row may be presented here several times in a join of type
 
1299
      UPDATE t1 FROM t1,t2 SET t1.a=t2.a
 
1300
 
 
1301
      In this case we will do the update for the first found row combination.
 
1302
      The join algorithm guarantees that we will not find the a row in
 
1303
      t1 several times.
 
1304
    */
 
1305
    if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
 
1306
      continue;
 
1307
 
 
1308
    /*
 
1309
      We can use compare_record() to optimize away updates if
 
1310
      the table handler is returning all columns OR if
 
1311
      if all updated columns are read
 
1312
    */
 
1313
    if (table == table_to_update)
 
1314
    {
 
1315
      bool can_compare_record;
 
1316
      can_compare_record= (!(table->file->ha_table_flags() &
 
1317
                             HA_PARTIAL_COLUMN_READ) ||
 
1318
                           bitmap_is_subset(table->write_set,
 
1319
                                            table->read_set));
 
1320
      table->status|= STATUS_UPDATED;
 
1321
      table->storeRecord();
 
1322
      if (fill_record(session, *fields_for_table[offset],
 
1323
                      *values_for_table[offset], 0))
 
1324
        return(1);
 
1325
 
 
1326
      found++;
 
1327
      if (!can_compare_record || table->compare_record())
 
1328
      {
 
1329
        int error;
 
1330
        if (!updated++)
 
1331
        {
 
1332
          /*
 
1333
            Inform the main table that we are going to update the table even
 
1334
            while we may be scanning it.  This will flush the read cache
 
1335
            if it's used.
 
1336
          */
 
1337
          main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
 
1338
        }
 
1339
        if ((error=table->file->ha_update_row(table->record[1],
 
1340
                                              table->record[0])) &&
 
1341
            error != HA_ERR_RECORD_IS_THE_SAME)
 
1342
        {
 
1343
          updated--;
 
1344
          if (!ignore ||
 
1345
              table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
1346
          {
 
1347
            /*
 
1348
              If (ignore && error == is ignorable) we don't have to
 
1349
              do anything; otherwise...
 
1350
            */
 
1351
            myf flags= 0;
 
1352
 
 
1353
            if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
1354
              flags|= ME_FATALERROR; /* Other handler errors are fatal */
 
1355
 
 
1356
            prepare_record_for_error_message(error, table);
 
1357
            table->file->print_error(error,MYF(flags));
 
1358
            return(1);
 
1359
          }
 
1360
        }
 
1361
        else
 
1362
        {
 
1363
          if (error == HA_ERR_RECORD_IS_THE_SAME)
 
1364
          {
 
1365
            error= 0;
 
1366
            updated--;
 
1367
          }
 
1368
          /* non-transactional or transactional table got modified   */
 
1369
          /* either multi_update class' flag is raised in its branch */
 
1370
          if (table->file->has_transactions())
 
1371
            transactional_tables= 1;
 
1372
          else
 
1373
          {
 
1374
            trans_safe= 0;
 
1375
            session->transaction.stmt.modified_non_trans_table= true;
 
1376
          }
 
1377
        }
 
1378
      }
 
1379
    }
 
1380
    else
 
1381
    {
 
1382
      int error;
 
1383
      Table *tmp_table= tmp_tables[offset];
 
1384
      /*
 
1385
       For updatable VIEW store rowid of the updated table and
 
1386
       rowids of tables used in the CHECK OPTION condition.
 
1387
      */
 
1388
      uint32_t field_num= 0;
 
1389
      List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
 
1390
      Table *tbl= table;
 
1391
      do
 
1392
      {
 
1393
        tbl->file->position(tbl->record[0]);
 
1394
        Field_varstring *ref_field=
 
1395
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
 
1396
        ref_field->store((char *)tbl->file->ref, tbl->file->ref_length,
 
1397
                         &my_charset_bin);
 
1398
        field_num++;
 
1399
      } while ((tbl= tbl_it++));
 
1400
 
 
1401
      /* Store regular updated fields in the row. */
 
1402
      fill_record(session,
 
1403
                  tmp_table->field + 1 + unupdated_check_opt_tables.elements,
 
1404
                  *values_for_table[offset], 1);
 
1405
 
 
1406
      /* Write row, ignoring duplicated updates to a row */
 
1407
      error= tmp_table->file->ha_write_row(tmp_table->record[0]);
 
1408
      if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
 
1409
      {
 
1410
        if (error &&
 
1411
            create_myisam_from_heap(session, tmp_table,
 
1412
                                         tmp_table_param[offset].start_recinfo,
 
1413
                                         &tmp_table_param[offset].recinfo,
 
1414
                                         error, 1))
 
1415
        {
 
1416
          do_update=0;
 
1417
          return(1);                    // Not a table_is_full error
 
1418
        }
 
1419
        found++;
 
1420
      }
 
1421
    }
 
1422
  }
 
1423
  return(0);
 
1424
}
 
1425
 
 
1426
 
 
1427
void multi_update::send_error(uint32_t errcode,const char *err)
 
1428
{
 
1429
  /* First send error what ever it is ... */
 
1430
  my_error(errcode, MYF(0), err);
 
1431
}
 
1432
 
 
1433
 
 
1434
void multi_update::abort()
 
1435
{
 
1436
  /* the error was handled or nothing deleted and no side effects return */
 
1437
  if (error_handled ||
 
1438
      (!session->transaction.stmt.modified_non_trans_table && !updated))
 
1439
    return;
 
1440
  /*
 
1441
    If all tables that has been updated are trans safe then just do rollback.
 
1442
    If not attempt to do remaining updates.
 
1443
  */
 
1444
 
 
1445
  if (! trans_safe)
 
1446
  {
 
1447
    assert(session->transaction.stmt.modified_non_trans_table);
 
1448
    if (do_update && table_count > 1)
 
1449
    {
 
1450
      /* Add warning here */
 
1451
      /*
 
1452
         todo/fixme: do_update() is never called with the arg 1.
 
1453
         should it change the signature to become argless?
 
1454
      */
 
1455
      do_updates();
 
1456
    }
 
1457
  }
 
1458
  if (session->transaction.stmt.modified_non_trans_table)
 
1459
  {
 
1460
    session->transaction.all.modified_non_trans_table= true;
 
1461
  }
 
1462
  assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
 
1463
}
 
1464
 
 
1465
 
 
1466
int multi_update::do_updates()
 
1467
{
 
1468
  TableList *cur_table;
 
1469
  int local_error= 0;
 
1470
  ha_rows org_updated;
 
1471
  Table *table, *tmp_table;
 
1472
  List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
 
1473
 
 
1474
  do_update= 0;                                 // Don't retry this function
 
1475
  if (!found)
 
1476
    return(0);
 
1477
  for (list<TableList*>::iterator it= update_tables.begin(); 
 
1478
       it != update_tables.end(); 
 
1479
       ++it)
 
1480
  {
 
1481
    cur_table= *it;
 
1482
    bool can_compare_record;
 
1483
    uint32_t offset= cur_table->shared;
 
1484
 
 
1485
    table = cur_table->table;
 
1486
    if (table == table_to_update)
 
1487
      continue;                                 // Already updated
 
1488
    org_updated= updated;
 
1489
    tmp_table= tmp_tables[cur_table->shared];
 
1490
    tmp_table->file->extra(HA_EXTRA_CACHE);     // Change to read cache
 
1491
    (void) table->file->ha_rnd_init(0);
 
1492
    table->file->extra(HA_EXTRA_NO_CACHE);
 
1493
 
 
1494
    check_opt_it.rewind();
 
1495
    while(Table *tbl= check_opt_it++)
 
1496
    {
 
1497
      if (tbl->file->ha_rnd_init(1))
 
1498
        goto err;
 
1499
      tbl->file->extra(HA_EXTRA_CACHE);
 
1500
    }
 
1501
 
 
1502
    /*
 
1503
      Setup copy functions to copy fields from temporary table
 
1504
    */
 
1505
    List_iterator_fast<Item> field_it(*fields_for_table[offset]);
 
1506
    Field **field= tmp_table->field +
 
1507
                   1 + unupdated_check_opt_tables.elements; // Skip row pointers
 
1508
    Copy_field *copy_field_ptr= copy_field, *copy_field_end;
 
1509
    for ( ; *field ; field++)
 
1510
    {
 
1511
      Item_field *item= (Item_field* ) field_it++;
 
1512
      (copy_field_ptr++)->set(item->field, *field, 0);
 
1513
    }
 
1514
    copy_field_end=copy_field_ptr;
 
1515
 
 
1516
    if ((local_error = tmp_table->file->ha_rnd_init(1)))
 
1517
      goto err;
 
1518
 
 
1519
    can_compare_record= (!(table->file->ha_table_flags() &
 
1520
                           HA_PARTIAL_COLUMN_READ) ||
 
1521
                         bitmap_is_subset(table->write_set,
 
1522
                                          table->read_set));
 
1523
 
 
1524
    for (;;)
 
1525
    {
 
1526
      if (session->killed && trans_safe)
 
1527
        goto err;
 
1528
      if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
 
1529
      {
 
1530
        if (local_error == HA_ERR_END_OF_FILE)
 
1531
          break;
 
1532
        if (local_error == HA_ERR_RECORD_DELETED)
 
1533
          continue;                             // May happen on dup key
 
1534
        goto err;
 
1535
      }
 
1536
 
 
1537
      /* call rnd_pos() using rowids from temporary table */
 
1538
      check_opt_it.rewind();
 
1539
      Table *tbl= table;
 
1540
      uint32_t field_num= 0;
 
1541
      do
 
1542
      {
 
1543
        Field_varstring *ref_field=
 
1544
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
 
1545
        if((local_error=
 
1546
              tbl->file->rnd_pos(tbl->record[0],
 
1547
                                (unsigned char *) ref_field->ptr
 
1548
                                 + ref_field->length_bytes)))
 
1549
          goto err;
 
1550
        field_num++;
 
1551
      } while((tbl= check_opt_it++));
 
1552
 
 
1553
      table->status|= STATUS_UPDATED;
 
1554
      table->storeRecord();
 
1555
 
 
1556
      /* Copy data from temporary table to current table */
 
1557
      for (copy_field_ptr=copy_field;
 
1558
           copy_field_ptr != copy_field_end;
 
1559
           copy_field_ptr++)
 
1560
        (*copy_field_ptr->do_copy)(copy_field_ptr);
 
1561
 
 
1562
      if (!can_compare_record || table->compare_record())
 
1563
      {
 
1564
        if ((local_error=table->file->ha_update_row(table->record[1],
 
1565
                                                    table->record[0])) &&
 
1566
            local_error != HA_ERR_RECORD_IS_THE_SAME)
 
1567
        {
 
1568
          if (!ignore ||
 
1569
              table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
 
1570
            goto err;
 
1571
        }
 
1572
        if (local_error != HA_ERR_RECORD_IS_THE_SAME)
 
1573
          updated++;
 
1574
        else
 
1575
          local_error= 0;
 
1576
      }
 
1577
    }
 
1578
 
 
1579
    if (updated != org_updated)
 
1580
    {
 
1581
      if (table->file->has_transactions())
 
1582
        transactional_tables= 1;
 
1583
      else
 
1584
      {
 
1585
        trans_safe= 0;                          // Can't do safe rollback
 
1586
        session->transaction.stmt.modified_non_trans_table= true;
 
1587
      }
 
1588
    }
 
1589
    (void) table->file->ha_rnd_end();
 
1590
    (void) tmp_table->file->ha_rnd_end();
 
1591
    check_opt_it.rewind();
 
1592
    while (Table *tbl= check_opt_it++)
 
1593
        tbl->file->ha_rnd_end();
 
1594
  }
 
1595
  return(0);
 
1596
 
 
1597
err:
 
1598
  {
 
1599
    prepare_record_for_error_message(local_error, table);
 
1600
    table->file->print_error(local_error,MYF(ME_FATALERROR));
 
1601
  }
 
1602
 
 
1603
  (void) table->file->ha_rnd_end();
 
1604
  (void) tmp_table->file->ha_rnd_end();
 
1605
  check_opt_it.rewind();
 
1606
  while (Table *tbl= check_opt_it++)
 
1607
      tbl->file->ha_rnd_end();
 
1608
 
 
1609
  if (updated != org_updated)
 
1610
  {
 
1611
    if (table->file->has_transactions())
 
1612
      transactional_tables= 1;
 
1613
    else
 
1614
    {
 
1615
      trans_safe= 0;
 
1616
      session->transaction.stmt.modified_non_trans_table= true;
 
1617
    }
 
1618
  }
 
1619
  return(1);
 
1620
}
 
1621
 
 
1622
 
 
1623
/* out: 1 if error, 0 if success */
 
1624
 
 
1625
bool multi_update::send_eof()
 
1626
{
 
1627
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1628
  uint64_t id;
 
1629
  Session::killed_state killed_status= Session::NOT_KILLED;
 
1630
 
 
1631
  session->set_proc_info("updating reference tables");
 
1632
 
 
1633
  /*
 
1634
     Does updates for the last n - 1 tables, returns 0 if ok;
 
1635
     error takes into account killed status gained in do_updates()
 
1636
  */
 
1637
  int local_error = (table_count) ? do_updates() : 0;
 
1638
  /*
 
1639
    if local_error is not set ON until after do_updates() then
 
1640
    later carried out killing should not affect binlogging.
 
1641
  */
 
1642
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
 
1643
  session->set_proc_info("end");
 
1644
 
 
1645
  /*
 
1646
    Write the SQL statement to the binlog if we updated
 
1647
    rows and we succeeded or if we updated some non
 
1648
    transactional tables.
 
1649
 
 
1650
    The query has to binlog because there's a modified non-transactional table
 
1651
    either from the query's list or via a stored routine: bug#13270,23333
 
1652
  */
 
1653
 
 
1654
  assert(trans_safe || !updated ||
 
1655
              session->transaction.stmt.modified_non_trans_table);
 
1656
  if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
 
1657
  {
 
1658
    if (session->transaction.stmt.modified_non_trans_table)
 
1659
      session->transaction.all.modified_non_trans_table= true;
 
1660
  }
 
1661
  if (local_error != 0)
 
1662
    error_handled= true; // to force early leave from ::send_error()
 
1663
 
 
1664
  if (local_error > 0) // if the above log write did not fail ...
 
1665
  {
 
1666
    /* Safety: If we haven't got an error before (can happen in do_updates) */
 
1667
    my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
 
1668
               MYF(0));
 
1669
    return true;
 
1670
  }
 
1671
 
 
1672
  id= session->arg_of_last_insert_id_function ?
 
1673
    session->first_successful_insert_id_in_prev_stmt : 0;
 
1674
  sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
 
1675
          (ulong) session->cuted_fields);
 
1676
  session->row_count_func=
 
1677
    (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
1678
  session->my_ok((ulong) session->row_count_func, id, buff);
 
1679
 
 
1680
  return false;
 
1681
}