~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

Cleanup around SAFEMALLOC

Show diffs side-by-side

added added

removed removed

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