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