~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Brian Aker
  • Date: 2010-01-27 18:58:12 UTC
  • Revision ID: brian@gaz-20100127185812-n62n0vwetnx8jrjy
Remove dead code.

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