~drizzle-trunk/drizzle/development

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