~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2008-08-01 22:33:44 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801223344-vzhlflfmtijp1imv
First pass at gettexizing the error messages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/*
18
18
  Single table and multi table updates of tables.
19
 
*/
20
 
 
21
 
#include <config.h>
22
 
 
23
 
#include <drizzled/sql_select.h>
24
 
#include <drizzled/error.h>
25
 
#include <drizzled/probes.h>
26
 
#include <drizzled/sql_base.h>
27
 
#include <drizzled/field/epoch.h>
28
 
#include <drizzled/sql_parse.h>
29
 
#include <drizzled/optimizer/range.h>
30
 
#include <drizzled/records.h>
31
 
#include <drizzled/internal/my_sys.h>
32
 
#include <drizzled/internal/iocache.h>
33
 
#include <drizzled/transaction_services.h>
34
 
#include <drizzled/filesort.h>
35
 
#include <drizzled/plugin/storage_engine.h>
36
 
 
37
 
#include <boost/dynamic_bitset.hpp>
38
 
#include <list>
39
 
 
40
 
using namespace std;
41
 
 
42
 
namespace drizzled
43
 
{
 
19
  Multi-table updates were introduced by Sinisa & Monty
 
20
*/
 
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
 
44
84
 
45
85
/**
46
86
  Re-read record if more columns are needed for error message.
47
87
 
48
88
  If we got a duplicate key error, we want to write an error
49
89
  message containing the value of the duplicate key. If we do not have
50
 
  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
51
91
  record with a proper read_set.
52
92
 
53
93
  @param[in] error   error number
54
94
  @param[in] table   table
55
95
*/
56
96
 
57
 
static void prepare_record_for_error_message(int error, Table *table)
 
97
static void prepare_record_for_error_message(int error, TABLE *table)
58
98
{
59
 
  Field **field_p= NULL;
60
 
  Field *field= NULL;
61
 
  uint32_t keynr= 0;
62
 
 
 
99
  Field **field_p;
 
100
  Field *field;
 
101
  uint keynr;
 
102
  MY_BITMAP unique_map; /* Fields in offended unique. */
 
103
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
 
104
  
63
105
  /*
64
106
    Only duplicate key errors print the key value.
65
107
    If storage engine does always read all columns, we have the value alraedy.
66
108
  */
67
109
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
68
 
      ! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
 
110
      !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
69
111
    return;
70
112
 
71
113
  /*
72
114
    Get the number of the offended index.
73
115
    We will see MAX_KEY if the engine cannot determine the affected index.
74
116
  */
75
 
  if ((keynr= table->get_dup_key(error)) >= MAX_KEY)
 
117
  if ((keynr= table->file->get_dup_key(error)) >= MAX_KEY)
76
118
    return;
77
119
 
78
120
  /* Create unique_map with all fields used by that index. */
79
 
  boost::dynamic_bitset<> unique_map(table->getShare()->sizeFields()); /* Fields in offended unique. */
80
 
  table->mark_columns_used_by_index_no_reset(keynr, unique_map);
 
121
  bitmap_init(&unique_map, unique_map_buf, table->s->fields, false);
 
122
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
81
123
 
82
124
  /* Subtract read_set and write_set. */
83
 
  unique_map-= *table->read_set;
84
 
  unique_map-= *table->write_set;
 
125
  bitmap_subtract(&unique_map, table->read_set);
 
126
  bitmap_subtract(&unique_map, table->write_set);
85
127
 
86
128
  /*
87
129
    If the unique index uses columns that are neither in read_set
88
130
    nor in write_set, we must re-read the record.
89
131
    Otherwise no need to do anything.
90
132
  */
91
 
  if (unique_map.none())
 
133
  if (bitmap_is_clear_all(&unique_map))
92
134
    return;
93
135
 
94
 
  /* Get identifier of last read record into table->cursor->ref. */
95
 
  table->cursor->position(table->getInsertRecord());
 
136
  /* Get identifier of last read record into table->file->ref. */
 
137
  table->file->position(table->record[0]);
96
138
  /* Add all fields used by unique index to read_set. */
97
 
  *table->read_set|= unique_map;
98
 
  /* Read record that is identified by table->cursor->ref. */
99
 
  (void) table->cursor->rnd_pos(table->getUpdateRecord(), table->cursor->ref);
 
139
  bitmap_union(table->read_set, &unique_map);
 
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);
100
144
  /* Copy the newly read columns into the new record. */
101
 
  for (field_p= table->getFields(); (field= *field_p); field_p++)
102
 
  {
103
 
    if (unique_map.test(field->position()))
104
 
    {
105
 
      field->copy_from_tmp(table->getShare()->rec_buff_length);
106
 
    }
107
 
  }
 
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);
108
148
 
109
149
  return;
110
150
}
114
154
  Process usual UPDATE
115
155
 
116
156
  SYNOPSIS
117
 
    update_query()
118
 
    session                     thread handler
 
157
    mysql_update()
 
158
    thd                 thread handler
119
159
    fields              fields for update
120
160
    values              values of fields for update
121
161
    conds               WHERE clause expression
122
162
    order_num           number of elemen in ORDER BY clause
123
 
    order               order_st BY clause list
 
163
    order               ORDER BY clause list
124
164
    limit               limit clause
125
165
    handle_duplicates   how to handle duplicates
126
166
 
127
167
  RETURN
128
168
    0  - OK
 
169
    2  - privilege check and openning table passed, but we need to convert to
 
170
         multi-update because of view substitution
129
171
    1  - error
130
172
*/
131
173
 
132
 
int update_query(Session *session, TableList *table_list,
133
 
                 List<Item> &fields, List<Item> &values, COND *conds,
134
 
                 uint32_t order_num, Order *order,
135
 
                 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)),
136
182
                 bool ignore)
137
183
{
138
184
  bool          using_limit= limit != HA_POS_ERROR;
139
 
  bool          used_key_is_modified;
140
 
  bool          transactional_table;
141
 
  int           error= 0;
 
185
  bool          safe_update= test(thd->options & OPTION_SAFE_UPDATES);
 
186
  bool          used_key_is_modified, transactional_table, will_batch;
 
187
  bool          can_compare_record;
 
188
  int           error, loc_error;
142
189
  uint          used_index= MAX_KEY, dup_key_found;
143
190
  bool          need_sort= true;
 
191
  uint          table_count= 0;
144
192
  ha_rows       updated, found;
145
193
  key_map       old_covering_keys;
146
 
  Table         *table;
147
 
  optimizer::SqlSelect *select= NULL;
148
 
  ReadRecord    info;
149
 
  Select_Lex    *select_lex= &session->getLex()->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;
150
199
  uint64_t     id;
151
200
  List<Item> all_fields;
152
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
153
 
 
154
 
  DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
155
 
  if (session->openTablesLock(table_list))
 
201
  THD::killed_state killed_status= THD::NOT_KILLED;
 
202
  
 
203
  for ( ; ; )
156
204
  {
157
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
158
 
    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);
159
213
  }
160
214
 
161
 
  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");
162
222
  table= table_list->table;
163
223
 
164
224
  /* Calculate "table->covering_keys" based on the WHERE */
165
 
  table->covering_keys= table->getShare()->keys_in_use;
166
 
  table->quick_keys.reset();
 
225
  table->covering_keys= table->s->keys_in_use;
 
226
  table->quick_keys.clear_all();
167
227
 
168
 
  if (prepare_update(session, table_list, &conds, order_num, order))
169
 
  {
170
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
171
 
    return 1;
172
 
  }
 
228
  if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
 
229
    goto abort;
173
230
 
174
231
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
175
232
  /* Check the fields we are going to modify */
176
 
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
177
 
  {
178
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
179
 
    return 1;
180
 
  }
181
 
 
 
233
  if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
 
234
    goto abort;                               /* purecov: inspected */
182
235
  if (table->timestamp_field)
183
236
  {
184
237
    // Don't set timestamp column if this is modified
185
 
    if (table->timestamp_field->isWriteSet())
186
 
    {
 
238
    if (bitmap_is_set(table->write_set,
 
239
                      table->timestamp_field->field_index))
187
240
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
188
 
    }
189
241
    else
190
242
    {
191
243
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
192
244
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
193
 
      {
194
 
        table->setWriteSet(table->timestamp_field->position());
195
 
      }
 
245
        bitmap_set_bit(table->write_set,
 
246
                       table->timestamp_field->field_index);
196
247
    }
197
248
  }
198
249
 
199
 
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
 
250
  if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
200
251
  {
201
 
    free_underlaid_joins(session, select_lex);
202
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
203
 
 
204
 
    return 1;
 
252
    free_underlaid_joins(thd, select_lex);
 
253
    goto abort;                               /* purecov: inspected */
205
254
  }
206
255
 
207
256
  if (select_lex->inner_refs_list.elements &&
208
 
    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))
209
258
  {
210
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
211
 
    return 1;
 
259
    MYSQL_UPDATE_END();
 
260
    return(-1);
212
261
  }
213
262
 
214
263
  if (conds)
215
264
  {
216
265
    Item::cond_result cond_value;
217
 
    conds= remove_eq_conds(session, conds, &cond_value);
 
266
    conds= remove_eq_conds(thd, conds, &cond_value);
218
267
    if (cond_value == Item::COND_FALSE)
219
268
      limit= 0;                                   // Impossible WHERE
220
269
  }
224
273
    update force the table handler to retrieve write-only fields to be able
225
274
    to compare records and detect data change.
226
275
  */
227
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
276
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
228
277
      table->timestamp_field &&
229
278
      (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
230
279
       table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
231
 
  {
232
 
    *table->read_set|= *table->write_set;
233
 
  }
 
280
    bitmap_union(table->read_set, table->write_set);
234
281
  // Don't count on usage of 'only index' when calculating which key to use
235
 
  table->covering_keys.reset();
236
 
 
237
 
  /* Update the table->cursor->stats.records number */
238
 
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
239
 
 
240
 
  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);
241
288
  if (error || !limit ||
242
 
      (select && select->check_quick(session, false, limit)))
 
289
      (select && select->check_quick(thd, safe_update, limit)))
243
290
  {
244
291
    delete select;
245
 
    /**
246
 
     * Resetting the Diagnostic area to prevent
247
 
     * lp bug# 439719
248
 
     */
249
 
    session->main_da.reset_diagnostics_area();
250
 
    free_underlaid_joins(session, select_lex);
251
 
    if (error || session->is_error())
252
 
    {
253
 
      DRIZZLE_UPDATE_DONE(1, 0, 0);
254
 
      return 1;
255
 
    }
256
 
    DRIZZLE_UPDATE_DONE(0, 0, 0);
257
 
    session->my_ok();                           // No matching records
258
 
    return 0;
 
292
    free_underlaid_joins(thd, select_lex);
 
293
    if (error)
 
294
      goto abort;                               // Error in where
 
295
    MYSQL_UPDATE_END();
 
296
    my_ok(thd);                         // No matching records
 
297
    return(0);
259
298
  }
260
299
  if (!select && limit != HA_POS_ERROR)
261
300
  {
262
 
    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)
263
302
      need_sort= false;
264
303
  }
265
304
  /* If running in safe sql mode, don't allow updates without keys */
266
 
  if (table->quick_keys.none())
 
305
  if (table->quick_keys.is_clear_all())
267
306
  {
268
 
    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
    }
269
314
  }
270
315
 
271
316
  table->mark_columns_needed_for_update();
272
317
 
273
318
  /* Check if we are modifying a key that we are used to search with */
274
 
 
 
319
  
275
320
  if (select && select->quick)
276
321
  {
277
322
    used_index= select->quick->index;
278
323
    used_key_is_modified= (!select->quick->unique_key_range() &&
279
 
                          select->quick->is_keys_used(*table->write_set));
 
324
                          select->quick->is_keys_used(table->write_set));
280
325
  }
281
326
  else
282
327
  {
283
328
    used_key_is_modified= 0;
284
329
    if (used_index == MAX_KEY)                  // no index for sort order
285
 
      used_index= table->cursor->key_used_on_scan;
 
330
      used_index= table->file->key_used_on_scan;
286
331
    if (used_index != MAX_KEY)
287
 
      used_key_is_modified= is_key_used(table, used_index, *table->write_set);
 
332
      used_key_is_modified= is_key_used(table, used_index, table->write_set);
288
333
  }
289
334
 
290
335
 
294
339
      We can't update table directly;  We must first search after all
295
340
      matching rows before updating the table!
296
341
    */
297
 
    if (used_index < MAX_KEY && old_covering_keys.test(used_index))
 
342
    if (used_index < MAX_KEY && old_covering_keys.is_set(used_index))
298
343
    {
299
344
      table->key_read=1;
300
345
      table->mark_columns_used_by_index(used_index);
308
353
    if (order && (need_sort || used_key_is_modified))
309
354
    {
310
355
      /*
311
 
        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
312
357
        to update
313
358
        NOTE: filesort will call table->prepare_for_position()
314
359
      */
315
 
      uint32_t         length= 0;
316
 
      SortField  *sortorder;
 
360
      uint         length= 0;
 
361
      SORT_FIELD  *sortorder;
317
362
      ha_rows examined_rows;
318
 
      FileSort filesort(*session);
319
 
 
320
 
      table->sort.io_cache= new internal::IO_CACHE;
321
 
 
 
363
 
 
364
      table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
 
365
                                                    MYF(MY_FAE | MY_ZEROFILL));
322
366
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
323
 
          (table->sort.found_records= filesort.run(table, sortorder, length,
324
 
                                                   select, limit, 1,
325
 
                                                   examined_rows)) == HA_POS_ERROR)
 
367
          (table->sort.found_records= filesort(thd, table, sortorder, length,
 
368
                                               select, limit, 1,
 
369
                                               &examined_rows))
 
370
          == HA_POS_ERROR)
326
371
      {
327
372
        goto err;
328
373
      }
330
375
        Filesort has already found and selected the rows we want to update,
331
376
        so we don't need the where clause
332
377
      */
333
 
      safe_delete(select);
 
378
      delete select;
 
379
      select= 0;
334
380
    }
335
381
    else
336
382
    {
340
386
        update these in a separate loop based on the pointer.
341
387
      */
342
388
 
343
 
      internal::IO_CACHE tempfile;
344
 
      if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
345
 
      {
 
389
      IO_CACHE tempfile;
 
390
      if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
 
391
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
346
392
        goto err;
347
 
      }
348
393
 
349
394
      /* If quick select is used, initialize it before retrieving rows. */
350
395
      if (select && select->quick && select->quick->reset())
351
396
        goto err;
352
 
      table->cursor->try_semi_consistent_read(1);
 
397
      table->file->try_semi_consistent_read(1);
353
398
 
354
399
      /*
355
400
        When we get here, we have one of the following options:
363
408
      */
364
409
 
365
410
      if (used_index == MAX_KEY || (select && select->quick))
366
 
      {
367
 
        if ((error= info.init_read_record(session, table, select, 0, true)))
368
 
          goto err;
369
 
      }
 
411
        init_read_record(&info,thd,table,select,0,1);
370
412
      else
371
 
      {
372
 
        if ((error= info.init_read_record_idx(session, table, 1, used_index)))
373
 
          goto err;
374
 
      }
 
413
        init_read_record_idx(&info, thd, table, 1, used_index);
375
414
 
376
 
      session->set_proc_info("Searching rows for update");
 
415
      thd_proc_info(thd, "Searching rows for update");
377
416
      ha_rows tmp_limit= limit;
378
417
 
379
 
      while (not(error= info.read_record(&info)) && not session->getKilled())
 
418
      while (!(error=info.read_record(&info)) && !thd->killed)
380
419
      {
381
420
        if (!(select && select->skip_record()))
382
421
        {
383
 
          if (table->cursor->was_semi_consistent_read())
 
422
          if (table->file->was_semi_consistent_read())
384
423
            continue;  /* repeat the read of the same row if it still exists */
385
424
 
386
 
          table->cursor->position(table->getInsertRecord());
387
 
          if (my_b_write(&tempfile,table->cursor->ref,
388
 
                         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))
389
428
          {
390
 
            error=1;
391
 
            break;
 
429
            error=1; /* purecov: inspected */
 
430
            break; /* purecov: inspected */
392
431
          }
393
432
          if (!--limit && using_limit)
394
433
          {
397
436
          }
398
437
        }
399
438
        else
400
 
          table->cursor->unlock_row();
 
439
          table->file->unlock_row();
401
440
      }
402
 
      if (session->getKilled() && not error)
 
441
      if (thd->killed && !error)
403
442
        error= 1;                               // Aborted
404
443
      limit= tmp_limit;
405
 
      table->cursor->try_semi_consistent_read(0);
406
 
      info.end_read_record();
407
 
 
 
444
      table->file->try_semi_consistent_read(0);
 
445
      end_read_record(&info);
 
446
     
408
447
      /* Change select to use tempfile */
409
448
      if (select)
410
449
      {
411
 
        safe_delete(select->quick);
 
450
        delete select->quick;
412
451
        if (select->free_cond)
413
452
          delete select->cond;
 
453
        select->quick=0;
414
454
        select->cond=0;
415
455
      }
416
456
      else
417
457
      {
418
 
        select= new optimizer::SqlSelect();
 
458
        select= new SQL_SELECT;
419
459
        select->head=table;
420
460
      }
421
 
      if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
422
 
        error=1;
423
 
      // Read row ptrs from this cursor
424
 
      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
425
464
      if (error >= 0)
426
465
        goto err;
427
466
    }
430
469
  }
431
470
 
432
471
  if (ignore)
433
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
434
 
 
 
472
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
473
  
435
474
  if (select && select->quick && select->quick->reset())
436
475
    goto err;
437
 
  table->cursor->try_semi_consistent_read(1);
438
 
  if ((error= info.init_read_record(session, table, select, 0, true)))
439
 
  {
440
 
    goto err;
441
 
  }
 
476
  table->file->try_semi_consistent_read(1);
 
477
  init_read_record(&info,thd,table,select,0,1);
442
478
 
443
479
  updated= found= 0;
444
 
  /*
445
 
   * Per the SQL standard, inserting NULL into a NOT NULL
446
 
   * field requires an error to be thrown.
447
 
   *
448
 
   * @NOTE
449
 
   *
450
 
   * NULL check and handling occurs in field_conv.cc
451
 
   */
452
 
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
453
 
  session->cuted_fields= 0L;
454
 
  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");
455
485
 
456
 
  transactional_table= table->cursor->has_transactions();
457
 
  session->setAbortOnWarning(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();
458
492
 
459
493
  /*
460
494
    Assure that we can use position()
461
495
    if we need to create an error message.
462
496
  */
463
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
 
497
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
464
498
    table->prepare_for_position();
465
499
 
466
 
  while (not (error=info.read_record(&info)) && not session->getKilled())
 
500
  /*
 
501
    We can use compare_record() to optimize away updates if
 
502
    the table handler is returning all columns OR if
 
503
    if all updated columns are read
 
504
  */
 
505
  can_compare_record= (!(table->file->ha_table_flags() &
 
506
                         HA_PARTIAL_COLUMN_READ) ||
 
507
                       bitmap_is_subset(table->write_set, table->read_set));
 
508
 
 
509
  while (!(error=info.read_record(&info)) && !thd->killed)
467
510
  {
468
 
    if (not (select && select->skip_record()))
 
511
    if (!(select && select->skip_record()))
469
512
    {
470
 
      if (table->cursor->was_semi_consistent_read())
 
513
      if (table->file->was_semi_consistent_read())
471
514
        continue;  /* repeat the read of the same row if it still exists */
472
515
 
473
 
      table->storeRecord();
474
 
      if (fill_record(session, fields, values))
475
 
        break;
 
516
      store_record(table,record[1]);
 
517
      if (fill_record(thd, fields, values, 0))
 
518
        break; /* purecov: inspected */
476
519
 
477
520
      found++;
478
521
 
479
 
      if (! table->records_are_comparable() || table->compare_records())
 
522
      if (!can_compare_record || compare_record(table))
480
523
      {
481
 
        /* Non-batched update */
482
 
        error= table->cursor->updateRecord(table->getUpdateRecord(),
483
 
                                            table->getInsertRecord());
484
 
 
485
 
        table->auto_increment_field_not_null= false;
486
 
 
 
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
        }
487
564
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
488
 
        {
 
565
        {
489
566
          if (error != HA_ERR_RECORD_IS_THE_SAME)
490
567
            updated++;
491
568
          else
492
569
            error= 0;
493
 
        }
494
 
        else if (! ignore ||
495
 
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
496
 
        {
 
570
        }
 
571
        else if (!ignore ||
 
572
                 table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
573
        {
497
574
          /*
498
575
            If (ignore && error is ignorable) we don't have to
499
576
            do anything; otherwise...
500
577
          */
501
578
          myf flags= 0;
502
579
 
503
 
          if (table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
580
          if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
504
581
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
505
582
 
506
583
          prepare_record_for_error_message(error, table);
507
 
          table->print_error(error,MYF(flags));
508
 
          error= 1;
509
 
          break;
510
 
        }
 
584
          table->file->print_error(error,MYF(flags));
 
585
          error= 1;
 
586
          break;
 
587
        }
511
588
      }
512
589
 
513
590
      if (!--limit && using_limit)
514
591
      {
515
 
        error= -1;                              // Simulate end of cursor
516
 
        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
        }
517
631
      }
518
632
    }
519
633
    else
520
 
      table->cursor->unlock_row();
521
 
    session->row_count++;
 
634
      table->file->unlock_row();
 
635
    thd->row_count++;
522
636
  }
523
637
  dup_key_found= 0;
524
638
  /*
529
643
    It's assumed that if an error was set in combination with an effective
530
644
    killed status then the error is due to killing.
531
645
  */
532
 
  killed_status= session->getKilled(); // get the status of the volatile
 
646
  killed_status= thd->killed; // get the status of the volatile
533
647
  // simulated killing after the loop must be ineffective for binlogging
534
 
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
535
 
 
536
 
  updated-= dup_key_found;
537
 
  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);
538
673
 
539
674
  if (!transactional_table && updated > 0)
540
 
    session->transaction.stmt.markModifiedNonTransData();
 
675
    thd->transaction.stmt.modified_non_trans_table= true;
541
676
 
542
 
  info.end_read_record();
 
677
  end_read_record(&info);
543
678
  delete select;
544
 
  session->set_proc_info("end");
545
 
  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));
546
681
 
547
682
  /*
548
683
    error < 0 means really no error at all: we processed all rows until the
549
684
    last one without error. error > 0 means an error (e.g. unique key
550
685
    violation and no IGNORE or REPLACE). error == 0 is also an error (if
551
686
    preparing the record or invoking before triggers fails). See
552
 
    autocommitOrRollback(error>=0) and return(error>=0) below.
 
687
    ha_autocommit_or_rollback(error>=0) and return(error>=0) below.
553
688
    Sometimes we want to binlog even if we updated no rows, in case user used
554
689
    it to be sure master and slave are in same state.
555
690
  */
556
 
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
 
691
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
557
692
  {
558
 
    if (session->transaction.stmt.hasModifiedNonTransData())
559
 
      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;
560
707
  }
561
 
  assert(transactional_table || !updated || session->transaction.stmt.hasModifiedNonTransData());
562
 
  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);
563
710
 
564
711
  /* If LAST_INSERT_ID(X) was used, report X */
565
 
  id= session->arg_of_last_insert_id_function ?
566
 
    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;
567
714
 
 
715
  MYSQL_UPDATE_END();
568
716
  if (error < 0)
569
717
  {
570
718
    char buff[STRING_BUFFER_USUAL_SIZE];
571
 
    snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
572
 
            (ulong) session->cuted_fields);
573
 
    session->row_count_func= updated;
574
 
    /**
575
 
     * Resetting the Diagnostic area to prevent
576
 
     * lp bug# 439719
577
 
     */
578
 
    session->main_da.reset_diagnostics_area();
579
 
    session->my_ok((ulong) session->rowCount(), found, id, buff);
580
 
    session->status_var.updated_row_count+= session->rowCount();
 
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);
581
724
  }
582
 
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;              /* calc cuted fields */
583
 
  session->setAbortOnWarning(false);
584
 
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
585
 
  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);
586
728
 
587
729
err:
588
 
  if (error != 0)
589
 
    table->print_error(error,MYF(0));
590
 
 
591
730
  delete select;
592
 
  free_underlaid_joins(session, select_lex);
 
731
  free_underlaid_joins(thd, select_lex);
593
732
  if (table->key_read)
594
733
  {
595
734
    table->key_read=0;
596
 
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
735
    table->file->extra(HA_EXTRA_NO_KEYREAD);
597
736
  }
598
 
  session->setAbortOnWarning(false);
 
737
  thd->abort_on_warning= 0;
599
738
 
600
 
  DRIZZLE_UPDATE_DONE(1, 0, 0);
601
 
  return 1;
 
739
abort:
 
740
  MYSQL_UPDATE_END();
 
741
  return(1);
602
742
}
603
743
 
604
744
/*
605
745
  Prepare items in UPDATE statement
606
746
 
607
747
  SYNOPSIS
608
 
    prepare_update()
609
 
    session                     - thread handler
 
748
    mysql_prepare_update()
 
749
    thd                 - thread handler
610
750
    table_list          - global/local table list
611
751
    conds               - conditions
612
752
    order_num           - number of ORDER BY list entries
616
756
    false OK
617
757
    true  error
618
758
*/
619
 
bool prepare_update(Session *session, TableList *table_list,
620
 
                         Item **conds, uint32_t order_num, Order *order)
 
759
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
 
760
                         Item **conds, uint order_num, ORDER *order)
621
761
{
622
762
  List<Item> all_fields;
623
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
624
 
 
625
 
  session->getLex()->allow_sum_func= 0;
626
 
 
627
 
  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, 
628
782
                                    &select_lex->top_join_list,
629
783
                                    table_list,
630
784
                                    &select_lex->leaf_tables,
631
785
                                    false) ||
632
 
      session->setup_conds(table_list, conds) ||
633
 
      select_lex->setup_ref_array(session, order_num) ||
634
 
      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,
635
789
                  table_list, all_fields, all_fields, order))
 
790
    return(true);
 
791
 
 
792
  /* Check that we are not using table that we are updating in a sub select */
 
793
  {
 
794
    TABLE_LIST *duplicate;
 
795
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
 
796
    {
 
797
      update_non_unique_table_error(table_list, "UPDATE", duplicate);
 
798
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
 
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);
636
1205
    return true;
637
 
 
638
 
  /* Check that we are not using table that we are updating in a sub select */
639
 
  {
640
 
    TableList *duplicate;
641
 
    if ((duplicate= unique_table(table_list, table_list->next_global)))
642
 
    {
643
 
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
644
 
      return true;
645
 
    }
 
1206
  default:
 
1207
    break;                                      // Avoid compler warning
646
1208
  }
647
 
 
648
1209
  return false;
649
 
}
650
 
 
651
 
} /* 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((char*) &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((char*) tmp_table->field[field_num]->ptr,
 
1457
               (char*) 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
}