~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2008-08-05 19:01:20 UTC
  • mto: (266.1.1 codestyle)
  • mto: This revision was merged to the branch mainline in revision 266.
  • Revision ID: monty@inaugust.com-20080805190120-tsuziqz2mfqcw7pe
Removed libmysyslt.la, made mysys a noinst_ and made everything use it. It's
not a standalone lib, there's no reason to pretend otherwise.

Show diffs side-by-side

added added

removed removed

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