~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

pandora-build v0.72 - Moved remaining hard-coded tests into pandora-build
macros.
Add PANDORA_DRIZZLE_BUILD to run the extra checks that drizzle needs that 
plugins would also need to run so we can just use that macro in generated
external plugin builds.
Added support to register_plugins for external plugin building.
Renamed register_plugins.py to pandora-plugin.

Show diffs side-by-side

added added

removed removed

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