~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_update.cc

  • Committer: Jay Pipes
  • Date: 2008-07-17 17:54:00 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717175400-xm2aazihjra8mdzq
Removal of DBUG from libdrizzle/ - Round 2

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
 
 
25
/* Return 0 if row hasn't changed */
 
26
 
 
27
bool compare_record(TABLE *table)
 
28
{
 
29
  if (table->s->blob_fields + table->s->varchar_fields == 0)
 
30
    return cmp_record(table,record[1]);
 
31
  /* Compare null bits */
 
32
  if (memcmp(table->null_flags,
 
33
             table->null_flags+table->s->rec_buff_length,
 
34
             table->s->null_bytes))
 
35
    return true;                                // Diff in NULL value
 
36
  /* Compare updated fields */
 
37
  for (Field **ptr= table->field ; *ptr ; ptr++)
 
38
  {
 
39
    if (bitmap_is_set(table->write_set, (*ptr)->field_index) &&
 
40
        (*ptr)->cmp_binary_offset(table->s->rec_buff_length))
 
41
      return true;
 
42
  }
 
43
  return false;
 
44
}
 
45
 
 
46
 
 
47
/*
 
48
  check that all fields are real fields
 
49
 
 
50
  SYNOPSIS
 
51
    check_fields()
 
52
    thd             thread handler
 
53
    items           Items for check
 
54
 
 
55
  RETURN
 
56
    true  Items can't be used in UPDATE
 
57
    false Items are OK
 
58
*/
 
59
 
 
60
static bool check_fields(THD *thd, List<Item> &items)
 
61
{
 
62
  List_iterator<Item> it(items);
 
63
  Item *item;
 
64
  Item_field *field;
 
65
 
 
66
  while ((item= it++))
 
67
  {
 
68
    if (!(field= item->filed_for_view_update()))
 
69
    {
 
70
      /* item has name, because it comes from VIEW SELECT list */
 
71
      my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
 
72
      return true;
 
73
    }
 
74
    /*
 
75
      we make temporary copy of Item_field, to avoid influence of changing
 
76
      result_field on Item_ref which refer on this field
 
77
    */
 
78
    thd->change_item_tree(it.ref(), new Item_field(thd, field));
 
79
  }
 
80
  return false;
 
81
}
 
82
 
44
83
 
45
84
/**
46
85
  Re-read record if more columns are needed for error message.
47
86
 
48
87
  If we got a duplicate key error, we want to write an error
49
88
  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
 
89
  all fields of the key value in record[0], we need to re-read the
51
90
  record with a proper read_set.
52
91
 
53
92
  @param[in] error   error number
54
93
  @param[in] table   table
55
94
*/
56
95
 
57
 
static void prepare_record_for_error_message(int error, Table *table)
 
96
static void prepare_record_for_error_message(int error, TABLE *table)
58
97
{
59
 
  Field **field_p= NULL;
60
 
  Field *field= NULL;
61
 
  uint32_t keynr= 0;
62
 
 
 
98
  Field **field_p;
 
99
  Field *field;
 
100
  uint keynr;
 
101
  MY_BITMAP unique_map; /* Fields in offended unique. */
 
102
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
 
103
  
63
104
  /*
64
105
    Only duplicate key errors print the key value.
65
106
    If storage engine does always read all columns, we have the value alraedy.
66
107
  */
67
108
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
68
 
      ! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
 
109
      !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
69
110
    return;
70
111
 
71
112
  /*
72
113
    Get the number of the offended index.
73
114
    We will see MAX_KEY if the engine cannot determine the affected index.
74
115
  */
75
 
  if ((keynr= table->get_dup_key(error)) >= MAX_KEY)
 
116
  if ((keynr= table->file->get_dup_key(error)) >= MAX_KEY)
76
117
    return;
77
118
 
78
119
  /* 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);
 
120
  bitmap_init(&unique_map, unique_map_buf, table->s->fields, false);
 
121
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
81
122
 
82
123
  /* Subtract read_set and write_set. */
83
 
  unique_map-= *table->read_set;
84
 
  unique_map-= *table->write_set;
 
124
  bitmap_subtract(&unique_map, table->read_set);
 
125
  bitmap_subtract(&unique_map, table->write_set);
85
126
 
86
127
  /*
87
128
    If the unique index uses columns that are neither in read_set
88
129
    nor in write_set, we must re-read the record.
89
130
    Otherwise no need to do anything.
90
131
  */
91
 
  if (unique_map.none())
 
132
  if (bitmap_is_clear_all(&unique_map))
92
133
    return;
93
134
 
94
 
  /* Get identifier of last read record into table->cursor->ref. */
95
 
  table->cursor->position(table->getInsertRecord());
 
135
  /* Get identifier of last read record into table->file->ref. */
 
136
  table->file->position(table->record[0]);
96
137
  /* 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);
 
138
  bitmap_union(table->read_set, &unique_map);
 
139
  /* Tell the engine about the new set. */
 
140
  table->file->column_bitmaps_signal();
 
141
  /* Read record that is identified by table->file->ref. */
 
142
  (void) table->file->rnd_pos(table->record[1], table->file->ref);
100
143
  /* 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
 
  }
 
144
  for (field_p= table->field; (field= *field_p); field_p++)
 
145
    if (bitmap_is_set(&unique_map, field->field_index))
 
146
      field->copy_from_tmp(table->s->rec_buff_length);
108
147
 
109
148
  return;
110
149
}
114
153
  Process usual UPDATE
115
154
 
116
155
  SYNOPSIS
117
 
    update_query()
118
 
    session                     thread handler
 
156
    mysql_update()
 
157
    thd                 thread handler
119
158
    fields              fields for update
120
159
    values              values of fields for update
121
160
    conds               WHERE clause expression
122
161
    order_num           number of elemen in ORDER BY clause
123
 
    order               order_st BY clause list
 
162
    order               ORDER BY clause list
124
163
    limit               limit clause
125
164
    handle_duplicates   how to handle duplicates
126
165
 
127
166
  RETURN
128
167
    0  - OK
 
168
    2  - privilege check and openning table passed, but we need to convert to
 
169
         multi-update because of view substitution
129
170
    1  - error
130
171
*/
131
172
 
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,
 
173
int mysql_update(THD *thd,
 
174
                 TABLE_LIST *table_list,
 
175
                 List<Item> &fields,
 
176
                 List<Item> &values,
 
177
                 COND *conds,
 
178
                 uint order_num, ORDER *order,
 
179
                 ha_rows limit,
 
180
                 enum enum_duplicates handle_duplicates __attribute__((__unused__)),
136
181
                 bool ignore)
137
182
{
138
183
  bool          using_limit= limit != HA_POS_ERROR;
139
 
  bool          used_key_is_modified;
140
 
  bool          transactional_table;
141
 
  int           error= 0;
 
184
  bool          safe_update= test(thd->options & OPTION_SAFE_UPDATES);
 
185
  bool          used_key_is_modified, transactional_table, will_batch;
 
186
  bool          can_compare_record;
 
187
  int           error, loc_error;
142
188
  uint          used_index= MAX_KEY, dup_key_found;
143
189
  bool          need_sort= true;
 
190
  uint          table_count= 0;
144
191
  ha_rows       updated, found;
145
192
  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;
 
193
  TABLE         *table;
 
194
  SQL_SELECT    *select;
 
195
  READ_RECORD   info;
 
196
  SELECT_LEX    *select_lex= &thd->lex->select_lex;
 
197
  bool          need_reopen;
150
198
  uint64_t     id;
151
199
  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))
 
200
  THD::killed_state killed_status= THD::NOT_KILLED;
 
201
  
 
202
  for ( ; ; )
156
203
  {
157
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
158
 
    return 1;
 
204
    if (open_tables(thd, &table_list, &table_count, 0))
 
205
      return(1);
 
206
 
 
207
    if (!lock_tables(thd, table_list, table_count, &need_reopen))
 
208
      break;
 
209
    if (!need_reopen)
 
210
      return(1);
 
211
    close_tables_for_reopen(thd, &table_list);
159
212
  }
160
213
 
161
 
  session->set_proc_info("init");
 
214
  if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
 
215
      (thd->fill_derived_tables() &&
 
216
       mysql_handle_derived(thd->lex, &mysql_derived_filling)))
 
217
    return(1);
 
218
 
 
219
  MYSQL_UPDATE_START();
 
220
  thd_proc_info(thd, "init");
162
221
  table= table_list->table;
163
222
 
164
223
  /* Calculate "table->covering_keys" based on the WHERE */
165
 
  table->covering_keys= table->getShare()->keys_in_use;
166
 
  table->quick_keys.reset();
 
224
  table->covering_keys= table->s->keys_in_use;
 
225
  table->quick_keys.clear_all();
167
226
 
168
 
  if (prepare_update(session, table_list, &conds, order_num, order))
169
 
  {
170
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
171
 
    return 1;
172
 
  }
 
227
  if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
 
228
    goto abort;
173
229
 
174
230
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
175
231
  /* 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
 
 
 
232
  if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
 
233
    goto abort;                               /* purecov: inspected */
182
234
  if (table->timestamp_field)
183
235
  {
184
236
    // Don't set timestamp column if this is modified
185
 
    if (table->timestamp_field->isWriteSet())
186
 
    {
 
237
    if (bitmap_is_set(table->write_set,
 
238
                      table->timestamp_field->field_index))
187
239
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
188
 
    }
189
240
    else
190
241
    {
191
242
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
192
243
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
193
 
      {
194
 
        table->setWriteSet(table->timestamp_field->position());
195
 
      }
 
244
        bitmap_set_bit(table->write_set,
 
245
                       table->timestamp_field->field_index);
196
246
    }
197
247
  }
198
248
 
199
 
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
 
249
  if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
200
250
  {
201
 
    free_underlaid_joins(session, select_lex);
202
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
203
 
 
204
 
    return 1;
 
251
    free_underlaid_joins(thd, select_lex);
 
252
    goto abort;                               /* purecov: inspected */
205
253
  }
206
254
 
207
255
  if (select_lex->inner_refs_list.elements &&
208
 
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
 
256
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
209
257
  {
210
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
211
 
    return 1;
 
258
    MYSQL_UPDATE_END();
 
259
    return(-1);
212
260
  }
213
261
 
214
262
  if (conds)
215
263
  {
216
264
    Item::cond_result cond_value;
217
 
    conds= remove_eq_conds(session, conds, &cond_value);
 
265
    conds= remove_eq_conds(thd, conds, &cond_value);
218
266
    if (cond_value == Item::COND_FALSE)
219
267
      limit= 0;                                   // Impossible WHERE
220
268
  }
224
272
    update force the table handler to retrieve write-only fields to be able
225
273
    to compare records and detect data change.
226
274
  */
227
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
275
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
228
276
      table->timestamp_field &&
229
277
      (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
230
278
       table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
231
 
  {
232
 
    *table->read_set|= *table->write_set;
233
 
  }
 
279
    bitmap_union(table->read_set, table->write_set);
234
280
  // 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);
 
281
  table->covering_keys.clear_all();
 
282
 
 
283
  /* Update the table->file->stats.records number */
 
284
  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
285
 
 
286
  select= make_select(table, 0, 0, conds, 0, &error);
241
287
  if (error || !limit ||
242
 
      (select && select->check_quick(session, false, limit)))
 
288
      (select && select->check_quick(thd, safe_update, limit)))
243
289
  {
244
290
    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;
 
291
    free_underlaid_joins(thd, select_lex);
 
292
    if (error)
 
293
      goto abort;                               // Error in where
 
294
    MYSQL_UPDATE_END();
 
295
    my_ok(thd);                         // No matching records
 
296
    return(0);
259
297
  }
260
298
  if (!select && limit != HA_POS_ERROR)
261
299
  {
262
 
    if ((used_index= optimizer::get_index_for_order(table, order, limit)) != MAX_KEY)
 
300
    if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY)
263
301
      need_sort= false;
264
302
  }
265
303
  /* If running in safe sql mode, don't allow updates without keys */
266
 
  if (table->quick_keys.none())
 
304
  if (table->quick_keys.is_clear_all())
267
305
  {
268
 
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
306
    thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
307
    if (safe_update && !using_limit)
 
308
    {
 
309
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
310
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
311
      goto err;
 
312
    }
269
313
  }
270
314
 
271
315
  table->mark_columns_needed_for_update();
272
316
 
273
317
  /* Check if we are modifying a key that we are used to search with */
274
 
 
 
318
  
275
319
  if (select && select->quick)
276
320
  {
277
321
    used_index= select->quick->index;
278
322
    used_key_is_modified= (!select->quick->unique_key_range() &&
279
 
                          select->quick->is_keys_used(*table->write_set));
 
323
                          select->quick->is_keys_used(table->write_set));
280
324
  }
281
325
  else
282
326
  {
283
327
    used_key_is_modified= 0;
284
328
    if (used_index == MAX_KEY)                  // no index for sort order
285
 
      used_index= table->cursor->key_used_on_scan;
 
329
      used_index= table->file->key_used_on_scan;
286
330
    if (used_index != MAX_KEY)
287
 
      used_key_is_modified= is_key_used(table, used_index, *table->write_set);
 
331
      used_key_is_modified= is_key_used(table, used_index, table->write_set);
288
332
  }
289
333
 
290
334
 
294
338
      We can't update table directly;  We must first search after all
295
339
      matching rows before updating the table!
296
340
    */
297
 
    if (used_index < MAX_KEY && old_covering_keys.test(used_index))
 
341
    if (used_index < MAX_KEY && old_covering_keys.is_set(used_index))
298
342
    {
299
343
      table->key_read=1;
300
344
      table->mark_columns_used_by_index(used_index);
308
352
    if (order && (need_sort || used_key_is_modified))
309
353
    {
310
354
      /*
311
 
        Doing an order_st BY;  Let filesort find and sort the rows we are going
 
355
        Doing an ORDER BY;  Let filesort find and sort the rows we are going
312
356
        to update
313
357
        NOTE: filesort will call table->prepare_for_position()
314
358
      */
315
 
      uint32_t         length= 0;
316
 
      SortField  *sortorder;
 
359
      uint         length= 0;
 
360
      SORT_FIELD  *sortorder;
317
361
      ha_rows examined_rows;
318
 
      FileSort filesort(*session);
319
 
 
320
 
      table->sort.io_cache= new internal::IO_CACHE;
321
 
 
 
362
 
 
363
      table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
 
364
                                                    MYF(MY_FAE | MY_ZEROFILL));
322
365
      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)
 
366
          (table->sort.found_records= filesort(thd, table, sortorder, length,
 
367
                                               select, limit, 1,
 
368
                                               &examined_rows))
 
369
          == HA_POS_ERROR)
326
370
      {
327
371
        goto err;
328
372
      }
330
374
        Filesort has already found and selected the rows we want to update,
331
375
        so we don't need the where clause
332
376
      */
333
 
      safe_delete(select);
 
377
      delete select;
 
378
      select= 0;
334
379
    }
335
380
    else
336
381
    {
340
385
        update these in a separate loop based on the pointer.
341
386
      */
342
387
 
343
 
      internal::IO_CACHE tempfile;
344
 
      if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
345
 
      {
 
388
      IO_CACHE tempfile;
 
389
      if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
 
390
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
346
391
        goto err;
347
 
      }
348
392
 
349
393
      /* If quick select is used, initialize it before retrieving rows. */
350
394
      if (select && select->quick && select->quick->reset())
351
395
        goto err;
352
 
      table->cursor->try_semi_consistent_read(1);
 
396
      table->file->try_semi_consistent_read(1);
353
397
 
354
398
      /*
355
399
        When we get here, we have one of the following options:
363
407
      */
364
408
 
365
409
      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
 
      }
 
410
        init_read_record(&info,thd,table,select,0,1);
370
411
      else
371
 
      {
372
 
        if ((error= info.init_read_record_idx(session, table, 1, used_index)))
373
 
          goto err;
374
 
      }
 
412
        init_read_record_idx(&info, thd, table, 1, used_index);
375
413
 
376
 
      session->set_proc_info("Searching rows for update");
 
414
      thd_proc_info(thd, "Searching rows for update");
377
415
      ha_rows tmp_limit= limit;
378
416
 
379
 
      while (not(error= info.read_record(&info)) && not session->getKilled())
 
417
      while (!(error=info.read_record(&info)) && !thd->killed)
380
418
      {
381
419
        if (!(select && select->skip_record()))
382
420
        {
383
 
          if (table->cursor->was_semi_consistent_read())
 
421
          if (table->file->was_semi_consistent_read())
384
422
            continue;  /* repeat the read of the same row if it still exists */
385
423
 
386
 
          table->cursor->position(table->getInsertRecord());
387
 
          if (my_b_write(&tempfile,table->cursor->ref,
388
 
                         table->cursor->ref_length))
 
424
          table->file->position(table->record[0]);
 
425
          if (my_b_write(&tempfile,table->file->ref,
 
426
                         table->file->ref_length))
389
427
          {
390
 
            error=1;
391
 
            break;
 
428
            error=1; /* purecov: inspected */
 
429
            break; /* purecov: inspected */
392
430
          }
393
431
          if (!--limit && using_limit)
394
432
          {
397
435
          }
398
436
        }
399
437
        else
400
 
          table->cursor->unlock_row();
 
438
          table->file->unlock_row();
401
439
      }
402
 
      if (session->getKilled() && not error)
 
440
      if (thd->killed && !error)
403
441
        error= 1;                               // Aborted
404
442
      limit= tmp_limit;
405
 
      table->cursor->try_semi_consistent_read(0);
406
 
      info.end_read_record();
407
 
 
 
443
      table->file->try_semi_consistent_read(0);
 
444
      end_read_record(&info);
 
445
     
408
446
      /* Change select to use tempfile */
409
447
      if (select)
410
448
      {
411
 
        safe_delete(select->quick);
 
449
        delete select->quick;
412
450
        if (select->free_cond)
413
451
          delete select->cond;
 
452
        select->quick=0;
414
453
        select->cond=0;
415
454
      }
416
455
      else
417
456
      {
418
 
        select= new optimizer::SqlSelect();
 
457
        select= new SQL_SELECT;
419
458
        select->head=table;
420
459
      }
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));
 
460
      if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
 
461
        error=1; /* purecov: inspected */
 
462
      select->file=tempfile;                    // Read row ptrs from this file
425
463
      if (error >= 0)
426
464
        goto err;
427
465
    }
430
468
  }
431
469
 
432
470
  if (ignore)
433
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
434
 
 
 
471
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
472
  
435
473
  if (select && select->quick && select->quick->reset())
436
474
    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
 
  }
 
475
  table->file->try_semi_consistent_read(1);
 
476
  init_read_record(&info,thd,table,select,0,1);
442
477
 
443
478
  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");
 
479
  /* Generate an error when trying to set a NOT NULL field to NULL. */
 
480
  thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
 
481
                                  : CHECK_FIELD_ERROR_FOR_NULL;
 
482
  thd->cuted_fields=0L;
 
483
  thd_proc_info(thd, "Updating");
455
484
 
456
 
  transactional_table= table->cursor->has_transactions();
457
 
  session->setAbortOnWarning(test(!ignore));
 
485
  transactional_table= table->file->has_transactions();
 
486
  thd->abort_on_warning= test(!ignore &&
 
487
                              (thd->variables.sql_mode &
 
488
                               (MODE_STRICT_TRANS_TABLES |
 
489
                                MODE_STRICT_ALL_TABLES)));
 
490
  will_batch= !table->file->start_bulk_update();
458
491
 
459
492
  /*
460
493
    Assure that we can use position()
461
494
    if we need to create an error message.
462
495
  */
463
 
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
 
496
  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
464
497
    table->prepare_for_position();
465
498
 
466
 
  while (not (error=info.read_record(&info)) && not session->getKilled())
 
499
  /*
 
500
    We can use compare_record() to optimize away updates if
 
501
    the table handler is returning all columns OR if
 
502
    if all updated columns are read
 
503
  */
 
504
  can_compare_record= (!(table->file->ha_table_flags() &
 
505
                         HA_PARTIAL_COLUMN_READ) ||
 
506
                       bitmap_is_subset(table->write_set, table->read_set));
 
507
 
 
508
  while (!(error=info.read_record(&info)) && !thd->killed)
467
509
  {
468
 
    if (not (select && select->skip_record()))
 
510
    if (!(select && select->skip_record()))
469
511
    {
470
 
      if (table->cursor->was_semi_consistent_read())
 
512
      if (table->file->was_semi_consistent_read())
471
513
        continue;  /* repeat the read of the same row if it still exists */
472
514
 
473
 
      table->storeRecord();
474
 
      if (fill_record(session, fields, values))
475
 
        break;
 
515
      store_record(table,record[1]);
 
516
      if (fill_record(thd, fields, values, 0))
 
517
        break; /* purecov: inspected */
476
518
 
477
519
      found++;
478
520
 
479
 
      if (! table->records_are_comparable() || table->compare_records())
 
521
      if (!can_compare_record || compare_record(table))
480
522
      {
481
 
        /* Non-batched update */
482
 
        error= table->cursor->updateRecord(table->getUpdateRecord(),
483
 
                                            table->getInsertRecord());
484
 
 
485
 
        table->auto_increment_field_not_null= false;
486
 
 
 
523
        if (will_batch)
 
524
        {
 
525
          /*
 
526
            Typically a batched handler can execute the batched jobs when:
 
527
            1) When specifically told to do so
 
528
            2) When it is not a good idea to batch anymore
 
529
            3) When it is necessary to send batch for other reasons
 
530
               (One such reason is when READ's must be performed)
 
531
 
 
532
            1) is covered by exec_bulk_update calls.
 
533
            2) and 3) is handled by the bulk_update_row method.
 
534
            
 
535
            bulk_update_row can execute the updates including the one
 
536
            defined in the bulk_update_row or not including the row
 
537
            in the call. This is up to the handler implementation and can
 
538
            vary from call to call.
 
539
 
 
540
            The dup_key_found reports the number of duplicate keys found
 
541
            in those updates actually executed. It only reports those if
 
542
            the extra call with HA_EXTRA_IGNORE_DUP_KEY have been issued.
 
543
            If this hasn't been issued it returns an error code and can
 
544
            ignore this number. Thus any handler that implements batching
 
545
            for UPDATE IGNORE must also handle this extra call properly.
 
546
 
 
547
            If a duplicate key is found on the record included in this
 
548
            call then it should be included in the count of dup_key_found
 
549
            and error should be set to 0 (only if these errors are ignored).
 
550
          */
 
551
          error= table->file->ha_bulk_update_row(table->record[1],
 
552
                                                 table->record[0],
 
553
                                                 &dup_key_found);
 
554
          limit+= dup_key_found;
 
555
          updated-= dup_key_found;
 
556
        }
 
557
        else
 
558
        {
 
559
          /* Non-batched update */
 
560
          error= table->file->ha_update_row(table->record[1],
 
561
                                            table->record[0]);
 
562
        }
487
563
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
488
 
        {
 
564
        {
489
565
          if (error != HA_ERR_RECORD_IS_THE_SAME)
490
566
            updated++;
491
567
          else
492
568
            error= 0;
493
 
        }
494
 
        else if (! ignore ||
495
 
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
496
 
        {
 
569
        }
 
570
        else if (!ignore ||
 
571
                 table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
572
        {
497
573
          /*
498
574
            If (ignore && error is ignorable) we don't have to
499
575
            do anything; otherwise...
500
576
          */
501
577
          myf flags= 0;
502
578
 
503
 
          if (table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
579
          if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
504
580
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
505
581
 
506
582
          prepare_record_for_error_message(error, table);
507
 
          table->print_error(error,MYF(flags));
508
 
          error= 1;
509
 
          break;
510
 
        }
 
583
          table->file->print_error(error,MYF(flags));
 
584
          error= 1;
 
585
          break;
 
586
        }
511
587
      }
512
588
 
513
589
      if (!--limit && using_limit)
514
590
      {
515
 
        error= -1;                              // Simulate end of cursor
516
 
        break;
 
591
        /*
 
592
          We have reached end-of-file in most common situations where no
 
593
          batching has occurred and if batching was supposed to occur but
 
594
          no updates were made and finally when the batch execution was
 
595
          performed without error and without finding any duplicate keys.
 
596
          If the batched updates were performed with errors we need to
 
597
          check and if no error but duplicate key's found we need to
 
598
          continue since those are not counted for in limit.
 
599
        */
 
600
        if (will_batch &&
 
601
            ((error= table->file->exec_bulk_update(&dup_key_found)) ||
 
602
             dup_key_found))
 
603
        {
 
604
          if (error)
 
605
          {
 
606
            /* purecov: begin inspected */
 
607
            /*
 
608
              The handler should not report error of duplicate keys if they
 
609
              are ignored. This is a requirement on batching handlers.
 
610
            */
 
611
            prepare_record_for_error_message(error, table);
 
612
            table->file->print_error(error,MYF(0));
 
613
            error= 1;
 
614
            break;
 
615
            /* purecov: end */
 
616
          }
 
617
          /*
 
618
            Either an error was found and we are ignoring errors or there
 
619
            were duplicate keys found. In both cases we need to correct
 
620
            the counters and continue the loop.
 
621
          */
 
622
          limit= dup_key_found; //limit is 0 when we get here so need to +
 
623
          updated-= dup_key_found;
 
624
        }
 
625
        else
 
626
        {
 
627
          error= -1;                            // Simulate end of file
 
628
          break;
 
629
        }
517
630
      }
518
631
    }
519
632
    else
520
 
      table->cursor->unlock_row();
521
 
    session->row_count++;
 
633
      table->file->unlock_row();
 
634
    thd->row_count++;
522
635
  }
523
636
  dup_key_found= 0;
524
637
  /*
529
642
    It's assumed that if an error was set in combination with an effective
530
643
    killed status then the error is due to killing.
531
644
  */
532
 
  killed_status= session->getKilled(); // get the status of the volatile
 
645
  killed_status= thd->killed; // get the status of the volatile
533
646
  // 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);
 
647
  error= (killed_status == THD::NOT_KILLED)?  error : 1;
 
648
 
 
649
  if (error &&
 
650
      will_batch &&
 
651
      (loc_error= table->file->exec_bulk_update(&dup_key_found)))
 
652
    /*
 
653
      An error has occurred when a batched update was performed and returned
 
654
      an error indication. It cannot be an allowed duplicate key error since
 
655
      we require the batching handler to treat this as a normal behavior.
 
656
 
 
657
      Otherwise we simply remove the number of duplicate keys records found
 
658
      in the batched update.
 
659
    */
 
660
  {
 
661
    /* purecov: begin inspected */
 
662
    prepare_record_for_error_message(loc_error, table);
 
663
    table->file->print_error(loc_error,MYF(ME_FATALERROR));
 
664
    error= 1;
 
665
    /* purecov: end */
 
666
  }
 
667
  else
 
668
    updated-= dup_key_found;
 
669
  if (will_batch)
 
670
    table->file->end_bulk_update();
 
671
  table->file->try_semi_consistent_read(0);
538
672
 
539
673
  if (!transactional_table && updated > 0)
540
 
    session->transaction.stmt.markModifiedNonTransData();
 
674
    thd->transaction.stmt.modified_non_trans_table= true;
541
675
 
542
 
  info.end_read_record();
 
676
  end_read_record(&info);
543
677
  delete select;
544
 
  session->set_proc_info("end");
545
 
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
678
  thd_proc_info(thd, "end");
 
679
  VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
546
680
 
547
681
  /*
548
682
    error < 0 means really no error at all: we processed all rows until the
549
683
    last one without error. error > 0 means an error (e.g. unique key
550
684
    violation and no IGNORE or REPLACE). error == 0 is also an error (if
551
685
    preparing the record or invoking before triggers fails). See
552
 
    autocommitOrRollback(error>=0) and return(error>=0) below.
 
686
    ha_autocommit_or_rollback(error>=0) and return(error>=0) below.
553
687
    Sometimes we want to binlog even if we updated no rows, in case user used
554
688
    it to be sure master and slave are in same state.
555
689
  */
556
 
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
 
690
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
557
691
  {
558
 
    if (session->transaction.stmt.hasModifiedNonTransData())
559
 
      session->transaction.all.markModifiedNonTransData();
 
692
    if (mysql_bin_log.is_open())
 
693
    {
 
694
      if (error < 0)
 
695
        thd->clear_error();
 
696
      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
 
697
                            thd->query, thd->query_length,
 
698
                            transactional_table, false, killed_status) &&
 
699
          transactional_table)
 
700
      {
 
701
        error=1;                                // Rollback update
 
702
      }
 
703
    }
 
704
    if (thd->transaction.stmt.modified_non_trans_table)
 
705
      thd->transaction.all.modified_non_trans_table= true;
560
706
  }
561
 
  assert(transactional_table || !updated || session->transaction.stmt.hasModifiedNonTransData());
562
 
  free_underlaid_joins(session, select_lex);
 
707
  assert(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
 
708
  free_underlaid_joins(thd, select_lex);
563
709
 
564
710
  /* 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;
 
711
  id= thd->arg_of_last_insert_id_function ?
 
712
    thd->first_successful_insert_id_in_prev_stmt : 0;
567
713
 
 
714
  MYSQL_UPDATE_END();
568
715
  if (error < 0)
569
716
  {
570
717
    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();
 
718
    sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
 
719
            (ulong) thd->cuted_fields);
 
720
    thd->row_count_func=
 
721
      (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
722
    my_ok(thd, (ulong) thd->row_count_func, id, buff);
581
723
  }
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);
 
724
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          /* calc cuted fields */
 
725
  thd->abort_on_warning= 0;
 
726
  return((error >= 0 || thd->is_error()) ? 1 : 0);
586
727
 
587
728
err:
588
 
  if (error != 0)
589
 
    table->print_error(error,MYF(0));
590
 
 
591
729
  delete select;
592
 
  free_underlaid_joins(session, select_lex);
 
730
  free_underlaid_joins(thd, select_lex);
593
731
  if (table->key_read)
594
732
  {
595
733
    table->key_read=0;
596
 
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
734
    table->file->extra(HA_EXTRA_NO_KEYREAD);
597
735
  }
598
 
  session->setAbortOnWarning(false);
 
736
  thd->abort_on_warning= 0;
599
737
 
600
 
  DRIZZLE_UPDATE_DONE(1, 0, 0);
601
 
  return 1;
 
738
abort:
 
739
  MYSQL_UPDATE_END();
 
740
  return(1);
602
741
}
603
742
 
604
743
/*
605
744
  Prepare items in UPDATE statement
606
745
 
607
746
  SYNOPSIS
608
 
    prepare_update()
609
 
    session                     - thread handler
 
747
    mysql_prepare_update()
 
748
    thd                 - thread handler
610
749
    table_list          - global/local table list
611
750
    conds               - conditions
612
751
    order_num           - number of ORDER BY list entries
616
755
    false OK
617
756
    true  error
618
757
*/
619
 
bool prepare_update(Session *session, TableList *table_list,
620
 
                         Item **conds, uint32_t order_num, Order *order)
 
758
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
 
759
                         Item **conds, uint order_num, ORDER *order)
621
760
{
 
761
  Item *fake_conds= 0;
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
  select_lex->fix_prepare_information(thd, conds, &fake_conds);
 
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
      if (!field)
 
1275
        return(1);
 
1276
      field->init(tbl);
 
1277
      /*
 
1278
        The field will be converted to varstring when creating tmp table if
 
1279
        table to be updated was created by mysql 4.1. Deny this.
 
1280
      */
 
1281
      field->can_alter_field_type= 0;
 
1282
      Item_field *ifield= new Item_field((Field *) field);
 
1283
      if (!ifield)
 
1284
         return(1);
 
1285
      ifield->maybe_null= 0;
 
1286
      if (temp_fields.push_back(ifield))
 
1287
        return(1);
 
1288
    } while ((tbl= tbl_it++));
 
1289
 
 
1290
    temp_fields.concat(fields_for_table[cnt]);
 
1291
 
 
1292
    /* Make an unique key over the first field to avoid duplicated updates */
 
1293
    bzero((char*) &group, sizeof(group));
 
1294
    group.asc= 1;
 
1295
    group.item= (Item**) temp_fields.head_ref();
 
1296
 
 
1297
    tmp_param->quick_group=1;
 
1298
    tmp_param->field_count=temp_fields.elements;
 
1299
    tmp_param->group_parts=1;
 
1300
    tmp_param->group_length= table->file->ref_length;
 
1301
    if (!(tmp_tables[cnt]=create_tmp_table(thd,
 
1302
                                           tmp_param,
 
1303
                                           temp_fields,
 
1304
                                           (ORDER*) &group, 0, 0,
 
1305
                                           TMP_TABLE_ALL_COLUMNS,
 
1306
                                           HA_POS_ERROR,
 
1307
                                           (char *) "")))
 
1308
      return(1);
 
1309
    tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
 
1310
  }
 
1311
  return(0);
 
1312
}
 
1313
 
 
1314
 
 
1315
multi_update::~multi_update()
 
1316
{
 
1317
  TABLE_LIST *table;
 
1318
  for (table= update_tables ; table; table= table->next_local)
 
1319
  {
 
1320
    table->table->no_keyread= table->table->no_cache= 0;
 
1321
    if (ignore)
 
1322
      table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
1323
  }
 
1324
 
 
1325
  if (tmp_tables)
 
1326
  {
 
1327
    for (uint cnt = 0; cnt < table_count; cnt++)
 
1328
    {
 
1329
      if (tmp_tables[cnt])
 
1330
      {
 
1331
        free_tmp_table(thd, tmp_tables[cnt]);
 
1332
        tmp_table_param[cnt].cleanup();
 
1333
      }
 
1334
    }
 
1335
  }
 
1336
  if (copy_field)
 
1337
    delete [] copy_field;
 
1338
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          // Restore this setting
 
1339
  assert(trans_safe || !updated ||
 
1340
              thd->transaction.all.modified_non_trans_table);
 
1341
}
 
1342
 
 
1343
 
 
1344
bool multi_update::send_data(List<Item> &not_used_values __attribute__((__unused__)))
 
1345
{
 
1346
  TABLE_LIST *cur_table;
 
1347
  
 
1348
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
 
1349
  {
 
1350
    TABLE *table= cur_table->table;
 
1351
    uint offset= cur_table->shared;
 
1352
    /*
 
1353
      Check if we are using outer join and we didn't find the row
 
1354
      or if we have already updated this row in the previous call to this
 
1355
      function.
 
1356
 
 
1357
      The same row may be presented here several times in a join of type
 
1358
      UPDATE t1 FROM t1,t2 SET t1.a=t2.a
 
1359
 
 
1360
      In this case we will do the update for the first found row combination.
 
1361
      The join algorithm guarantees that we will not find the a row in
 
1362
      t1 several times.
 
1363
    */
 
1364
    if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
 
1365
      continue;
 
1366
 
 
1367
    /*
 
1368
      We can use compare_record() to optimize away updates if
 
1369
      the table handler is returning all columns OR if
 
1370
      if all updated columns are read
 
1371
    */
 
1372
    if (table == table_to_update)
 
1373
    {
 
1374
      bool can_compare_record;
 
1375
      can_compare_record= (!(table->file->ha_table_flags() &
 
1376
                             HA_PARTIAL_COLUMN_READ) ||
 
1377
                           bitmap_is_subset(table->write_set,
 
1378
                                            table->read_set));
 
1379
      table->status|= STATUS_UPDATED;
 
1380
      store_record(table,record[1]);
 
1381
      if (fill_record(thd, *fields_for_table[offset],
 
1382
                      *values_for_table[offset], 0))
 
1383
        return(1);
 
1384
 
 
1385
      found++;
 
1386
      if (!can_compare_record || compare_record(table))
 
1387
      {
 
1388
        int error;
 
1389
        if (!updated++)
 
1390
        {
 
1391
          /*
 
1392
            Inform the main table that we are going to update the table even
 
1393
            while we may be scanning it.  This will flush the read cache
 
1394
            if it's used.
 
1395
          */
 
1396
          main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
 
1397
        }
 
1398
        if ((error=table->file->ha_update_row(table->record[1],
 
1399
                                              table->record[0])) &&
 
1400
            error != HA_ERR_RECORD_IS_THE_SAME)
 
1401
        {
 
1402
          updated--;
 
1403
          if (!ignore ||
 
1404
              table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
1405
          {
 
1406
            /*
 
1407
              If (ignore && error == is ignorable) we don't have to
 
1408
              do anything; otherwise...
 
1409
            */
 
1410
            myf flags= 0;
 
1411
 
 
1412
            if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
1413
              flags|= ME_FATALERROR; /* Other handler errors are fatal */
 
1414
 
 
1415
            prepare_record_for_error_message(error, table);
 
1416
            table->file->print_error(error,MYF(flags));
 
1417
            return(1);
 
1418
          }
 
1419
        }
 
1420
        else
 
1421
        {
 
1422
          if (error == HA_ERR_RECORD_IS_THE_SAME)
 
1423
          {
 
1424
            error= 0;
 
1425
            updated--;
 
1426
          }
 
1427
          /* non-transactional or transactional table got modified   */
 
1428
          /* either multi_update class' flag is raised in its branch */
 
1429
          if (table->file->has_transactions())
 
1430
            transactional_tables= 1;
 
1431
          else
 
1432
          {
 
1433
            trans_safe= 0;
 
1434
            thd->transaction.stmt.modified_non_trans_table= true;
 
1435
          }
 
1436
        }
 
1437
      }
 
1438
    }
 
1439
    else
 
1440
    {
 
1441
      int error;
 
1442
      TABLE *tmp_table= tmp_tables[offset];
 
1443
      /*
 
1444
       For updatable VIEW store rowid of the updated table and
 
1445
       rowids of tables used in the CHECK OPTION condition.
 
1446
      */
 
1447
      uint field_num= 0;
 
1448
      List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
 
1449
      TABLE *tbl= table;
 
1450
      do
 
1451
      {
 
1452
        tbl->file->position(tbl->record[0]);
 
1453
        memcpy((char*) tmp_table->field[field_num]->ptr,
 
1454
               (char*) tbl->file->ref, tbl->file->ref_length);
 
1455
        field_num++;
 
1456
      } while ((tbl= tbl_it++));
 
1457
 
 
1458
      /* Store regular updated fields in the row. */
 
1459
      fill_record(thd,
 
1460
                  tmp_table->field + 1 + unupdated_check_opt_tables.elements,
 
1461
                  *values_for_table[offset], 1);
 
1462
 
 
1463
      /* Write row, ignoring duplicated updates to a row */
 
1464
      error= tmp_table->file->ha_write_row(tmp_table->record[0]);
 
1465
      if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
 
1466
      {
 
1467
        if (error &&
 
1468
            create_myisam_from_heap(thd, tmp_table,
 
1469
                                         tmp_table_param[offset].start_recinfo,
 
1470
                                         &tmp_table_param[offset].recinfo,
 
1471
                                         error, 1))
 
1472
        {
 
1473
          do_update=0;
 
1474
          return(1);                    // Not a table_is_full error
 
1475
        }
 
1476
        found++;
 
1477
      }
 
1478
    }
 
1479
  }
 
1480
  return(0);
 
1481
}
 
1482
 
 
1483
 
 
1484
void multi_update::send_error(uint errcode,const char *err)
 
1485
{
 
1486
  /* First send error what ever it is ... */
 
1487
  my_error(errcode, MYF(0), err);
 
1488
}
 
1489
 
 
1490
 
 
1491
void multi_update::abort()
 
1492
{
 
1493
  /* the error was handled or nothing deleted and no side effects return */
 
1494
  if (error_handled ||
 
1495
      (!thd->transaction.stmt.modified_non_trans_table && !updated))
 
1496
    return;
 
1497
  /*
 
1498
    If all tables that has been updated are trans safe then just do rollback.
 
1499
    If not attempt to do remaining updates.
 
1500
  */
 
1501
 
 
1502
  if (! trans_safe)
 
1503
  {
 
1504
    assert(thd->transaction.stmt.modified_non_trans_table);
 
1505
    if (do_update && table_count > 1)
 
1506
    {
 
1507
      /* Add warning here */
 
1508
      /* 
 
1509
         todo/fixme: do_update() is never called with the arg 1.
 
1510
         should it change the signature to become argless?
 
1511
      */
 
1512
      VOID(do_updates());
 
1513
    }
 
1514
  }
 
1515
  if (thd->transaction.stmt.modified_non_trans_table)
 
1516
  {
 
1517
    /*
 
1518
      The query has to binlog because there's a modified non-transactional table
 
1519
      either from the query's list or via a stored routine: bug#13270,23333
 
1520
    */
 
1521
    if (mysql_bin_log.is_open())
 
1522
    {
 
1523
      /*
 
1524
        THD::killed status might not have been set ON at time of an error
 
1525
        got caught and if happens later the killed error is written
 
1526
        into repl event.
 
1527
      */
 
1528
      thd->binlog_query(THD::ROW_QUERY_TYPE,
 
1529
                        thd->query, thd->query_length,
 
1530
                        transactional_tables, false);
 
1531
    }
 
1532
    thd->transaction.all.modified_non_trans_table= true;
 
1533
  }
 
1534
  assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
 
1535
}
 
1536
 
 
1537
 
 
1538
int multi_update::do_updates()
 
1539
{
 
1540
  TABLE_LIST *cur_table;
 
1541
  int local_error= 0;
 
1542
  ha_rows org_updated;
 
1543
  TABLE *table, *tmp_table;
 
1544
  List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
 
1545
  
 
1546
  do_update= 0;                                 // Don't retry this function
 
1547
  if (!found)
 
1548
    return(0);
 
1549
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
 
1550
  {
 
1551
    bool can_compare_record;
 
1552
    uint offset= cur_table->shared;
 
1553
 
 
1554
    table = cur_table->table;
 
1555
    if (table == table_to_update)
 
1556
      continue;                                 // Already updated
 
1557
    org_updated= updated;
 
1558
    tmp_table= tmp_tables[cur_table->shared];
 
1559
    tmp_table->file->extra(HA_EXTRA_CACHE);     // Change to read cache
 
1560
    (void) table->file->ha_rnd_init(0);
 
1561
    table->file->extra(HA_EXTRA_NO_CACHE);
 
1562
 
 
1563
    check_opt_it.rewind();
 
1564
    while(TABLE *tbl= check_opt_it++)
 
1565
    {
 
1566
      if (tbl->file->ha_rnd_init(1))
 
1567
        goto err;
 
1568
      tbl->file->extra(HA_EXTRA_CACHE);
 
1569
    }
 
1570
 
 
1571
    /*
 
1572
      Setup copy functions to copy fields from temporary table
 
1573
    */
 
1574
    List_iterator_fast<Item> field_it(*fields_for_table[offset]);
 
1575
    Field **field= tmp_table->field + 
 
1576
                   1 + unupdated_check_opt_tables.elements; // Skip row pointers
 
1577
    Copy_field *copy_field_ptr= copy_field, *copy_field_end;
 
1578
    for ( ; *field ; field++)
 
1579
    {
 
1580
      Item_field *item= (Item_field* ) field_it++;
 
1581
      (copy_field_ptr++)->set(item->field, *field, 0);
 
1582
    }
 
1583
    copy_field_end=copy_field_ptr;
 
1584
 
 
1585
    if ((local_error = tmp_table->file->ha_rnd_init(1)))
 
1586
      goto err;
 
1587
 
 
1588
    can_compare_record= (!(table->file->ha_table_flags() &
 
1589
                           HA_PARTIAL_COLUMN_READ) ||
 
1590
                         bitmap_is_subset(table->write_set,
 
1591
                                          table->read_set));
 
1592
 
 
1593
    for (;;)
 
1594
    {
 
1595
      if (thd->killed && trans_safe)
 
1596
        goto err;
 
1597
      if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
 
1598
      {
 
1599
        if (local_error == HA_ERR_END_OF_FILE)
 
1600
          break;
 
1601
        if (local_error == HA_ERR_RECORD_DELETED)
 
1602
          continue;                             // May happen on dup key
 
1603
        goto err;
 
1604
      }
 
1605
 
 
1606
      /* call rnd_pos() using rowids from temporary table */
 
1607
      check_opt_it.rewind();
 
1608
      TABLE *tbl= table;
 
1609
      uint field_num= 0;
 
1610
      do
 
1611
      {
 
1612
        if((local_error=
 
1613
              tbl->file->rnd_pos(tbl->record[0],
 
1614
                                (uchar *) tmp_table->field[field_num]->ptr)))
 
1615
          goto err;
 
1616
        field_num++;
 
1617
      } while((tbl= check_opt_it++));
 
1618
 
 
1619
      table->status|= STATUS_UPDATED;
 
1620
      store_record(table,record[1]);
 
1621
 
 
1622
      /* Copy data from temporary table to current table */
 
1623
      for (copy_field_ptr=copy_field;
 
1624
           copy_field_ptr != copy_field_end;
 
1625
           copy_field_ptr++)
 
1626
        (*copy_field_ptr->do_copy)(copy_field_ptr);
 
1627
 
 
1628
      if (!can_compare_record || compare_record(table))
 
1629
      {
 
1630
        if ((local_error=table->file->ha_update_row(table->record[1],
 
1631
                                                    table->record[0])) &&
 
1632
            local_error != HA_ERR_RECORD_IS_THE_SAME)
 
1633
        {
 
1634
          if (!ignore ||
 
1635
              table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
 
1636
            goto err;
 
1637
        }
 
1638
        if (local_error != HA_ERR_RECORD_IS_THE_SAME)
 
1639
          updated++;
 
1640
        else
 
1641
          local_error= 0;
 
1642
      }
 
1643
    }
 
1644
 
 
1645
    if (updated != org_updated)
 
1646
    {
 
1647
      if (table->file->has_transactions())
 
1648
        transactional_tables= 1;
 
1649
      else
 
1650
      {
 
1651
        trans_safe= 0;                          // Can't do safe rollback
 
1652
        thd->transaction.stmt.modified_non_trans_table= true;
 
1653
      }
 
1654
    }
 
1655
    (void) table->file->ha_rnd_end();
 
1656
    (void) tmp_table->file->ha_rnd_end();
 
1657
    check_opt_it.rewind();
 
1658
    while (TABLE *tbl= check_opt_it++)
 
1659
        tbl->file->ha_rnd_end();
 
1660
 
 
1661
  }
 
1662
  return(0);
 
1663
 
 
1664
err:
 
1665
  {
 
1666
    prepare_record_for_error_message(local_error, table);
 
1667
    table->file->print_error(local_error,MYF(ME_FATALERROR));
 
1668
  }
 
1669
 
 
1670
  (void) table->file->ha_rnd_end();
 
1671
  (void) tmp_table->file->ha_rnd_end();
 
1672
  check_opt_it.rewind();
 
1673
  while (TABLE *tbl= check_opt_it++)
 
1674
      tbl->file->ha_rnd_end();
 
1675
 
 
1676
  if (updated != org_updated)
 
1677
  {
 
1678
    if (table->file->has_transactions())
 
1679
      transactional_tables= 1;
 
1680
    else
 
1681
    {
 
1682
      trans_safe= 0;
 
1683
      thd->transaction.stmt.modified_non_trans_table= true;
 
1684
    }
 
1685
  }
 
1686
  return(1);
 
1687
}
 
1688
 
 
1689
 
 
1690
/* out: 1 if error, 0 if success */
 
1691
 
 
1692
bool multi_update::send_eof()
 
1693
{
 
1694
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1695
  uint64_t id;
 
1696
  THD::killed_state killed_status= THD::NOT_KILLED;
 
1697
  
 
1698
  thd_proc_info(thd, "updating reference tables");
 
1699
 
 
1700
  /* 
 
1701
     Does updates for the last n - 1 tables, returns 0 if ok;
 
1702
     error takes into account killed status gained in do_updates()
 
1703
  */
 
1704
  int local_error = (table_count) ? do_updates() : 0;
 
1705
  /*
 
1706
    if local_error is not set ON until after do_updates() then
 
1707
    later carried out killing should not affect binlogging.
 
1708
  */
 
1709
  killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
 
1710
  thd_proc_info(thd, "end");
 
1711
 
 
1712
  /*
 
1713
    Write the SQL statement to the binlog if we updated
 
1714
    rows and we succeeded or if we updated some non
 
1715
    transactional tables.
 
1716
    
 
1717
    The query has to binlog because there's a modified non-transactional table
 
1718
    either from the query's list or via a stored routine: bug#13270,23333
 
1719
  */
 
1720
 
 
1721
  assert(trans_safe || !updated || 
 
1722
              thd->transaction.stmt.modified_non_trans_table);
 
1723
  if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
 
1724
  {
 
1725
    if (mysql_bin_log.is_open())
 
1726
    {
 
1727
      if (local_error == 0)
 
1728
        thd->clear_error();
 
1729
      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
 
1730
                            thd->query, thd->query_length,
 
1731
                            transactional_tables, false, killed_status) &&
 
1732
          trans_safe)
 
1733
      {
 
1734
        local_error= 1;                         // Rollback update
 
1735
      }
 
1736
    }
 
1737
    if (thd->transaction.stmt.modified_non_trans_table)
 
1738
      thd->transaction.all.modified_non_trans_table= true;
 
1739
  }
 
1740
  if (local_error != 0)
 
1741
    error_handled= true; // to force early leave from ::send_error()
 
1742
 
 
1743
  if (local_error > 0) // if the above log write did not fail ...
 
1744
  {
 
1745
    /* Safety: If we haven't got an error before (can happen in do_updates) */
 
1746
    my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
 
1747
               MYF(0));
 
1748
    return(true);
 
1749
  }
 
1750
 
 
1751
  id= thd->arg_of_last_insert_id_function ?
 
1752
    thd->first_successful_insert_id_in_prev_stmt : 0;
 
1753
  sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
 
1754
          (ulong) thd->cuted_fields);
 
1755
  thd->row_count_func=
 
1756
    (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
1757
  ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
 
1758
  return(false);
 
1759
}