~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
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
28
#include <bitset>
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
29
#include <list>
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
30
31
using namespace std;
32
1 by brian
clean slate
33
/*
34
  check that all fields are real fields
35
36
  SYNOPSIS
37
    check_fields()
520.1.22 by Brian Aker
Second pass of thd cleanup
38
    session             thread handler
1 by brian
clean slate
39
    items           Items for check
40
41
  RETURN
56 by brian
Next pass of true/false update.
42
    true  Items can't be used in UPDATE
43
    false Items are OK
1 by brian
clean slate
44
*/
45
520.1.22 by Brian Aker
Second pass of thd cleanup
46
static bool check_fields(Session *session, List<Item> &items)
1 by brian
clean slate
47
{
48
  List_iterator<Item> it(items);
49
  Item *item;
50
  Item_field *field;
51
52
  while ((item= it++))
53
  {
54
    if (!(field= item->filed_for_view_update()))
55
    {
56
      /* item has name, because it comes from VIEW SELECT list */
57
      my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
56 by brian
Next pass of true/false update.
58
      return true;
1 by brian
clean slate
59
    }
60
    /*
61
      we make temporary copy of Item_field, to avoid influence of changing
62
      result_field on Item_ref which refer on this field
63
    */
520.1.22 by Brian Aker
Second pass of thd cleanup
64
    session->change_item_tree(it.ref(), new Item_field(session, field));
1 by brian
clean slate
65
  }
56 by brian
Next pass of true/false update.
66
  return false;
1 by brian
clean slate
67
}
68
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;
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
86
  bitset<MAX_FIELDS> unique_map; /* Fields in offended unique */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
87
1 by brian
clean slate
88
  /*
89
    Only duplicate key errors print the key value.
90
    If storage engine does always read all columns, we have the value alraedy.
91
  */
92
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
93
      !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ))
51.2.2 by Patrick Galbraith
Removed DBUGs from
94
    return;
1 by brian
clean slate
95
96
  /*
97
    Get the number of the offended index.
98
    We will see MAX_KEY if the engine cannot determine the affected index.
99
  */
100
  if ((keynr= table->file->get_dup_key(error)) >= MAX_KEY)
51.2.2 by Patrick Galbraith
Removed DBUGs from
101
    return;
1 by brian
clean slate
102
103
  /* Create unique_map with all fields used by that index. */
104
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
105
106
  /* Subtract read_set and write_set. */
993.1.8 by Padraig O'Sullivan
Removed my_bitmap.[cc,h] files from the mysys directory. Also removed them
107
  unique_map&= table->read_set->flip();
108
  unique_map&= table->write_set->flip();
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
109
  table->read_set->flip();
110
  table->write_set->flip();
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
  */
982.1.1 by Padraig O'Sullivan
Initial work on removing MY_BITMAP from the Drizzle code base. For a start,
117
  if (unique_map.none())
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. */
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
123
  *(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++)
982.1.1 by Padraig O'Sullivan
Initial work on removing MY_BITMAP from the Drizzle code base. For a start,
128
    if (unique_map.test(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;
993.1.4 by Padraig O'Sullivan
Initial work on replacement of Bitmap<> from the code. Removed the 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
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
214
    if (table->write_set->test(table->timestamp_field->field_index))
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)
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
220
        table->write_set->set(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))
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
254
    *(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
993.1.4 by Padraig O'Sullivan
Initial work on replacement of Bitmap<> from the code. Removed the 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 */
993.1.4 by Padraig O'Sullivan
Initial work on replacement of Bitmap<> from the code. Removed the 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
    */
993.1.4 by Padraig O'Sullivan
Initial work on replacement of Bitmap<> from the code. Removed the 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) ||
982.1.13 by Padraig O'Sullivan
Removed the isBitmapSubset method. Can perform the same operation using the
485
                       ((*table->read_set & *table->write_set) == *table->write_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 */
850
    if (table->timestamp_field &&
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
851
        table->write_set->test(table->timestamp_field->field_index))
1 by brian
clean slate
852
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
853
854
    /* if table will be updated then check that it is unique */
855
    if (table->map & tables_for_update)
856
    {
857
      table->mark_columns_needed_for_update();
858
      /*
859
        If table will be updated we should not downgrade lock for it and
860
        leave it as is.
861
      */
862
    }
863
    else
864
    {
865
      /*
866
        If we are using the binary log, we need TL_READ_NO_INSERT to get
867
        correct order of statements. Otherwise, we use a TL_READ lock to
868
        improve performance.
869
      */
604 by Brian Aker
Remove lock condition needed (we do row based replication, so... lock is
870
      tl->lock_type= TL_READ;
1 by brian
clean slate
871
      tl->updating= 0;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
872
      /* Update Table::lock_type accordingly. */
1 by brian
clean slate
873
      if (!tl->placeholder() && !using_lock_tables)
874
        tl->table->reginfo.lock_type= tl->lock_type;
875
    }
876
  }
877
878
  /* now lock and fill tables */
520.1.22 by Brian Aker
Second pass of thd cleanup
879
  if (lock_tables(session, table_list, table_count, &need_reopen))
1 by brian
clean slate
880
  {
881
    if (!need_reopen)
836 by Brian Aker
Fixed session call from function to method.
882
      return true;
1 by brian
clean slate
883
884
    /*
885
      We have to reopen tables since some of them were altered or dropped
886
      during lock_tables() or something was done with their triggers.
887
      Let us do some cleanups to be able do setup_table() and setup_fields()
888
      once again.
889
    */
890
    List_iterator_fast<Item> it(*fields);
891
    Item *item;
892
    while ((item= it++))
893
      item->cleanup();
894
895
    /* We have to cleanup translation tables of views. */
327.2.4 by Brian Aker
Refactoring table.h
896
    for (TableList *tbl= table_list; tbl; tbl= tbl->next_global)
1 by brian
clean slate
897
      tbl->cleanup_items();
898
520.1.22 by Brian Aker
Second pass of thd cleanup
899
    close_tables_for_reopen(session, &table_list);
1 by brian
clean slate
900
    goto reopen_tables;
901
  }
902
903
  /*
904
    Check that we are not using table that we are updating, but we should
905
    skip all tables of UPDATE SELECT itself
906
  */
56 by brian
Next pass of true/false update.
907
  lex->select_lex.exclude_from_table_unique_test= true;
1 by brian
clean slate
908
  /* We only need SELECT privilege for columns in the values list */
909
  for (tl= leaves; tl; tl= tl->next_leaf)
910
  {
911
    if (tl->lock_type != TL_READ &&
912
        tl->lock_type != TL_READ_NO_INSERT)
913
    {
327.2.4 by Brian Aker
Refactoring table.h
914
      TableList *duplicate;
520.1.22 by Brian Aker
Second pass of thd cleanup
915
      if ((duplicate= unique_table(session, tl, table_list, 0)))
1 by brian
clean slate
916
      {
917
        update_non_unique_table_error(table_list, "UPDATE", duplicate);
836 by Brian Aker
Fixed session call from function to method.
918
        return true;
1 by brian
clean slate
919
      }
920
    }
921
  }
922
  /*
56 by brian
Next pass of true/false update.
923
    Set exclude_from_table_unique_test value back to false. It is needed for
1 by brian
clean slate
924
    further check in multi_update::prepare whether to use record cache.
925
  */
56 by brian
Next pass of true/false update.
926
  lex->select_lex.exclude_from_table_unique_test= false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
927
520.1.22 by Brian Aker
Second pass of thd cleanup
928
  if (session->fill_derived_tables() &&
1 by brian
clean slate
929
      mysql_handle_derived(lex, &mysql_derived_filling))
836 by Brian Aker
Fixed session call from function to method.
930
    return true;
1 by brian
clean slate
931
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
932
  return (false);
1 by brian
clean slate
933
}
934
935
936
/*
937
  Setup multi-update handling and call SELECT to do the join
938
*/
939
520.1.22 by Brian Aker
Second pass of thd cleanup
940
bool mysql_multi_update(Session *session,
327.2.4 by Brian Aker
Refactoring table.h
941
                        TableList *table_list,
1 by brian
clean slate
942
                        List<Item> *fields,
943
                        List<Item> *values,
944
                        COND *conds,
151 by Brian Aker
Ulonglong to uint64_t
945
                        uint64_t options,
1 by brian
clean slate
946
                        enum enum_duplicates handle_duplicates, bool ignore,
848 by Brian Aker
typdef class removal (just... use the name of the class).
947
                        Select_Lex_Unit *unit, Select_Lex *select_lex)
1 by brian
clean slate
948
{
949
  multi_update *result;
950
  bool res;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
951
1 by brian
clean slate
952
  if (!(result= new multi_update(table_list,
520.1.22 by Brian Aker
Second pass of thd cleanup
953
				 session->lex->select_lex.leaf_tables,
1 by brian
clean slate
954
				 fields, values,
955
				 handle_duplicates, ignore)))
836 by Brian Aker
Fixed session call from function to method.
956
    return true;
1 by brian
clean slate
957
520.1.22 by Brian Aker
Second pass of thd cleanup
958
  session->abort_on_warning= true;
1 by brian
clean slate
959
960
  List<Item> total_list;
520.1.22 by Brian Aker
Second pass of thd cleanup
961
  res= mysql_select(session, &select_lex->ref_pointer_array,
1 by brian
clean slate
962
                      table_list, select_lex->with_wild,
963
                      total_list,
327.2.3 by Brian Aker
Refactoring of class Table
964
                      conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
1 by brian
clean slate
965
                      options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
966
                      OPTION_SETUP_TABLES_DONE,
967
                      result, unit, select_lex);
520.1.22 by Brian Aker
Second pass of thd cleanup
968
  res|= session->is_error();
1 by brian
clean slate
969
  if (unlikely(res))
970
  {
971
    /* If we had a another error reported earlier then this will be ignored */
972
    result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
973
    result->abort();
974
  }
975
  delete result;
520.1.22 by Brian Aker
Second pass of thd cleanup
976
  session->abort_on_warning= 0;
836 by Brian Aker
Fixed session call from function to method.
977
  return false;
1 by brian
clean slate
978
}
979
980
327.2.4 by Brian Aker
Refactoring table.h
981
multi_update::multi_update(TableList *table_list,
982
			   TableList *leaves_list,
1 by brian
clean slate
983
			   List<Item> *field_list, List<Item> *value_list,
984
			   enum enum_duplicates handle_duplicates_arg,
985
                           bool ignore_arg)
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
986
  :all_tables(table_list), leaves(leaves_list),
1 by brian
clean slate
987
   tmp_tables(0), updated(0), found(0), fields(field_list),
988
   values(value_list), table_count(0), copy_field(0),
989
   handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
990
   transactional_tables(0), ignore(ignore_arg), error_handled(0)
991
{}
992
993
994
/*
995
  Connect fields with tables and create list of tables that are updated
996
*/
997
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
998
int multi_update::prepare(List<Item> &,
848 by Brian Aker
typdef class removal (just... use the name of the class).
999
                          Select_Lex_Unit *)
1 by brian
clean slate
1000
{
327.2.4 by Brian Aker
Refactoring table.h
1001
  TableList *table_ref;
1 by brian
clean slate
1002
  table_map tables_to_update;
1003
  Item_field *item;
1004
  List_iterator_fast<Item> field_it(*fields);
1005
  List_iterator_fast<Item> value_it(*values);
482 by Brian Aker
Remove uint.
1006
  uint32_t i, max_fields;
1007
  uint32_t leaf_table_count= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1008
520.1.22 by Brian Aker
Second pass of thd cleanup
1009
  session->count_cuted_fields= CHECK_FIELD_WARN;
1010
  session->cuted_fields=0L;
1011
  session->set_proc_info("updating main table");
1 by brian
clean slate
1012
1013
  tables_to_update= get_table_map(fields);
1014
1015
  if (!tables_to_update)
1016
  {
1017
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
51.2.2 by Patrick Galbraith
Removed DBUGs from
1018
    return(1);
1 by brian
clean slate
1019
  }
1020
1021
  /*
1022
    We have to check values after setup_tables to get covering_keys right in
1023
    reference tables
1024
  */
1025
520.1.22 by Brian Aker
Second pass of thd cleanup
1026
  if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1027
    return(1);
1 by brian
clean slate
1028
1029
  /*
1030
    Save tables beeing updated in update_tables
1031
    update_table->shared is position for table
1032
    Don't use key read on tables that are updated
1033
  */
1034
  for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1035
  {
1036
    /* 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
1037
    Table *table=table_ref->table;
1 by brian
clean slate
1038
    leaf_table_count++;
1039
    if (tables_to_update & table->map)
1040
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1041
      TableList *tl= (TableList*) session->memdup((char*) table_ref,
1 by brian
clean slate
1042
						sizeof(*tl));
1043
      if (!tl)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1044
	return(1);
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1045
      update_tables.push_back(tl);
1 by brian
clean slate
1046
      tl->shared= table_count++;
1047
      table->no_keyread=1;
993.1.4 by Padraig O'Sullivan
Initial work on replacement of Bitmap<> from the code. Removed the Bitmap<>
1048
      table->covering_keys.reset();
1 by brian
clean slate
1049
      table->pos_in_table_list= tl;
1050
    }
1051
  }
1052
1053
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1054
  table_count=  update_tables.size();
1 by brian
clean slate
1055
520.1.22 by Brian Aker
Second pass of thd cleanup
1056
  tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1057
  tmp_table_param = (Tmp_Table_Param*) session->calloc(sizeof(Tmp_Table_Param) *
1 by brian
clean slate
1058
						   table_count);
520.1.22 by Brian Aker
Second pass of thd cleanup
1059
  fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1060
					      table_count);
1061
  values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1062
					      table_count);
1063
  if (session->is_fatal_error)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1064
    return(1);
1 by brian
clean slate
1065
  for (i=0 ; i < table_count ; i++)
1066
  {
1067
    fields_for_table[i]= new List_item;
1068
    values_for_table[i]= new List_item;
1069
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1070
  if (session->is_fatal_error)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1071
    return(1);
1 by brian
clean slate
1072
1073
  /* Split fields into fields_for_table[] and values_by_table[] */
1074
1075
  while ((item= (Item_field *) field_it++))
1076
  {
1077
    Item *value= value_it++;
482 by Brian Aker
Remove uint.
1078
    uint32_t offset= item->field->table->pos_in_table_list->shared;
1 by brian
clean slate
1079
    fields_for_table[offset]->push_back(item);
1080
    values_for_table[offset]->push_back(value);
1081
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1082
  if (session->is_fatal_error)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1083
    return(1);
1 by brian
clean slate
1084
1085
  /* Allocate copy fields */
1086
  max_fields=0;
1087
  for (i=0 ; i < table_count ; i++)
1088
    set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
1089
  copy_field= new Copy_field[max_fields];
520.1.22 by Brian Aker
Second pass of thd cleanup
1090
  return(session->is_fatal_error != 0);
1 by brian
clean slate
1091
}
1092
1093
1094
/*
1095
  Check if table is safe to update on fly
1096
1097
  SYNOPSIS
1098
    safe_update_on_fly()
520.1.22 by Brian Aker
Second pass of thd cleanup
1099
    session                 Thread handler
1 by brian
clean slate
1100
    join_tab            How table is used in join
1101
    all_tables          List of tables
1102
1103
  NOTES
1104
    We can update the first table in join on the fly if we know that
1105
    a row in this table will never be read twice. This is true under
1106
    the following conditions:
1107
1108
    - We are doing a table scan and the data is in a separate file (MyISAM) or
1109
      if we don't update a clustered key.
1110
1111
    - We are doing a range scan and we don't update the scan key or
1112
      the primary key for a clustered table handler.
1113
1114
    - Table is not joined to itself.
1115
1116
    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
1117
    the Table::write_set bitmap.
1 by brian
clean slate
1118
1119
  WARNING
1120
    This code is a bit dependent of how make_join_readinfo() works.
1121
1122
  RETURN
1123
    0		Not safe to update
1124
    1		Safe to update
1125
*/
1126
520.1.22 by Brian Aker
Second pass of thd cleanup
1127
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
327.2.4 by Brian Aker
Refactoring table.h
1128
                               TableList *table_ref, TableList *all_tables)
1 by brian
clean slate
1129
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1130
  Table *table= join_tab->table;
520.1.22 by Brian Aker
Second pass of thd cleanup
1131
  if (unique_table(session, table_ref, all_tables, 0))
1 by brian
clean slate
1132
    return 0;
1133
  switch (join_tab->type) {
1134
  case JT_SYSTEM:
1135
  case JT_CONST:
1136
  case JT_EQ_REF:
56 by brian
Next pass of true/false update.
1137
    return true;				// At most one matching row
1 by brian
clean slate
1138
  case JT_REF:
1139
  case JT_REF_OR_NULL:
1140
    return !is_key_used(table, join_tab->ref.key, table->write_set);
1141
  case JT_ALL:
1142
    /* If range search on index */
1143
    if (join_tab->quick)
1144
      return !join_tab->quick->is_keys_used(table->write_set);
1145
    /* If scanning in clustered key */
1146
    if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1147
	table->s->primary_key < MAX_KEY)
1148
      return !is_key_used(table, table->s->primary_key, table->write_set);
56 by brian
Next pass of true/false update.
1149
    return true;
1 by brian
clean slate
1150
  default:
1151
    break;					// Avoid compler warning
1152
  }
56 by brian
Next pass of true/false update.
1153
  return false;
1 by brian
clean slate
1154
1155
}
1156
1157
1158
/*
1159
  Initialize table for multi table
1160
1161
  IMPLEMENTATION
1162
    - Update first table in join on the fly, if possible
1163
    - Create temporary tables to store changed values for all other tables
1164
      that are updated (and main_table if the above doesn't hold).
1165
*/
1166
1167
bool
1168
multi_update::initialize_tables(JOIN *join)
1169
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1170
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1171
    return(1);
1 by brian
clean slate
1172
  main_table=join->join_tab->table;
1173
  table_to_update= 0;
1174
1175
  /* Any update has at least one pair (field, value) */
51.2.2 by Patrick Galbraith
Removed DBUGs from
1176
  assert(fields->elements);
1 by brian
clean slate
1177
1178
  /* 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
1179
  for (list<TableList*>::iterator it= update_tables.begin(); 
1180
       it != update_tables.end(); 
1181
       ++it)
1 by brian
clean slate
1182
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1183
    Table *table= (*it)->table;
1184
    uint32_t cnt= (*it)->shared;
1 by brian
clean slate
1185
    List<Item> temp_fields;
327.2.3 by Brian Aker
Refactoring of class Table
1186
    order_st     group;
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1187
    Tmp_Table_Param *tmp_param;
1 by brian
clean slate
1188
1189
    table->mark_columns_needed_for_update();
1190
    if (ignore)
1191
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1192
    if (table == main_table)			// First table in join
1193
    {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1194
      if (safe_update_on_fly(session, join->join_tab, (*it), all_tables))
1 by brian
clean slate
1195
      {
1196
	table_to_update= main_table;		// Update table on the fly
1197
	continue;
1198
      }
1199
    }
1200
    table->prepare_for_position();
1201
1202
    tmp_param= tmp_table_param+cnt;
1203
1204
    /*
1205
      Create a temporary table to store all fields that are changed for this
1206
      table. The first field in the temporary table is a pointer to the
1207
      original row so that we can find and update it. For the updatable
1208
      VIEW a few following fields are rowids of tables used in the CHECK
1209
      OPTION condition.
1210
    */
1211
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1212
    List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1213
    Table *tbl= table;
1 by brian
clean slate
1214
    do
1215
    {
241 by Brian Aker
First pass of CHAR removal.
1216
      Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1217
                                                  tbl->alias, tbl->s, &my_charset_bin);
1 by brian
clean slate
1218
      if (!field)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1219
        return(1);
1 by brian
clean slate
1220
      field->init(tbl);
1221
      /*
1222
        The field will be converted to varstring when creating tmp table if
1223
        table to be updated was created by mysql 4.1. Deny this.
1224
      */
1225
      Item_field *ifield= new Item_field((Field *) field);
1226
      if (!ifield)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1227
         return(1);
1 by brian
clean slate
1228
      ifield->maybe_null= 0;
1229
      if (temp_fields.push_back(ifield))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1230
        return(1);
1 by brian
clean slate
1231
    } while ((tbl= tbl_it++));
1232
1233
    temp_fields.concat(fields_for_table[cnt]);
1234
1235
    /* 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().
1236
    memset(&group, 0, sizeof(group));
1 by brian
clean slate
1237
    group.asc= 1;
1238
    group.item= (Item**) temp_fields.head_ref();
1239
1240
    tmp_param->quick_group=1;
1241
    tmp_param->field_count=temp_fields.elements;
1242
    tmp_param->group_parts=1;
1243
    tmp_param->group_length= table->file->ref_length;
520.1.22 by Brian Aker
Second pass of thd cleanup
1244
    if (!(tmp_tables[cnt]=create_tmp_table(session,
1 by brian
clean slate
1245
					   tmp_param,
1246
					   temp_fields,
327.2.3 by Brian Aker
Refactoring of class Table
1247
					   (order_st*) &group, 0, 0,
1 by brian
clean slate
1248
					   TMP_TABLE_ALL_COLUMNS,
1249
					   HA_POS_ERROR,
1250
					   (char *) "")))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1251
      return(1);
1 by brian
clean slate
1252
    tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
1253
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1254
  return(0);
1 by brian
clean slate
1255
}
1256
1257
1258
multi_update::~multi_update()
1259
{
327.2.4 by Brian Aker
Refactoring table.h
1260
  TableList *table;
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1261
  for (list<TableList*>::iterator it= update_tables.begin(); 
1262
       it != update_tables.end(); 
1263
       ++it)
1 by brian
clean slate
1264
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1265
    table= *it;
1 by brian
clean slate
1266
    table->table->no_keyread= table->table->no_cache= 0;
1267
    if (ignore)
1268
      table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1269
  }
1270
1271
  if (tmp_tables)
1272
  {
482 by Brian Aker
Remove uint.
1273
    for (uint32_t cnt = 0; cnt < table_count; cnt++)
1 by brian
clean slate
1274
    {
1275
      if (tmp_tables[cnt])
1276
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
1277
	tmp_tables[cnt]->free_tmp_table(session);
1 by brian
clean slate
1278
	tmp_table_param[cnt].cleanup();
1279
      }
1280
    }
1281
  }
1282
  if (copy_field)
1283
    delete [] copy_field;
520.1.22 by Brian Aker
Second pass of thd cleanup
1284
  session->count_cuted_fields= CHECK_FIELD_IGNORE;		// Restore this setting
77.1.45 by Monty Taylor
Warning fixes.
1285
  assert(trans_safe || !updated ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1286
              session->transaction.all.modified_non_trans_table);
1 by brian
clean slate
1287
}
1288
1289
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
1290
bool multi_update::send_data(List<Item> &)
1 by brian
clean slate
1291
{
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1292
  for (list<TableList*>::iterator it= update_tables.begin(); 
1293
       it != update_tables.end(); 
1294
       ++it)
1 by brian
clean slate
1295
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1296
    Table *table= (*it)->table;
1297
    uint32_t offset= (*it)->shared;
1 by brian
clean slate
1298
    /*
1299
      Check if we are using outer join and we didn't find the row
1300
      or if we have already updated this row in the previous call to this
1301
      function.
1302
1303
      The same row may be presented here several times in a join of type
1304
      UPDATE t1 FROM t1,t2 SET t1.a=t2.a
1305
1306
      In this case we will do the update for the first found row combination.
1307
      The join algorithm guarantees that we will not find the a row in
1308
      t1 several times.
1309
    */
1310
    if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
1311
      continue;
1312
1313
    /*
1314
      We can use compare_record() to optimize away updates if
1315
      the table handler is returning all columns OR if
1316
      if all updated columns are read
1317
    */
1318
    if (table == table_to_update)
1319
    {
1320
      bool can_compare_record;
1321
      can_compare_record= (!(table->file->ha_table_flags() &
1322
                             HA_PARTIAL_COLUMN_READ) ||
982.1.13 by Padraig O'Sullivan
Removed the isBitmapSubset method. Can perform the same operation using the
1323
                           ((*table->read_set & *table->write_set) == *table->write_set));
1 by brian
clean slate
1324
      table->status|= STATUS_UPDATED;
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
1325
      table->storeRecord();
520.1.22 by Brian Aker
Second pass of thd cleanup
1326
      if (fill_record(session, *fields_for_table[offset],
1 by brian
clean slate
1327
                      *values_for_table[offset], 0))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1328
	return(1);
1 by brian
clean slate
1329
1330
      found++;
355 by Brian Aker
More Table cleanup
1331
      if (!can_compare_record || table->compare_record())
1 by brian
clean slate
1332
      {
1333
	int error;
1334
        if (!updated++)
1335
        {
1336
          /*
1337
            Inform the main table that we are going to update the table even
1338
            while we may be scanning it.  This will flush the read cache
1339
            if it's used.
1340
          */
1341
          main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
1342
        }
1343
        if ((error=table->file->ha_update_row(table->record[1],
1344
                                              table->record[0])) &&
1345
            error != HA_ERR_RECORD_IS_THE_SAME)
1346
        {
1347
          updated--;
1348
          if (!ignore ||
1349
              table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
1350
          {
1351
            /*
1352
              If (ignore && error == is ignorable) we don't have to
1353
              do anything; otherwise...
1354
            */
1355
            myf flags= 0;
1356
1357
            if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
1358
              flags|= ME_FATALERROR; /* Other handler errors are fatal */
1359
1360
            prepare_record_for_error_message(error, table);
1361
            table->file->print_error(error,MYF(flags));
51.2.2 by Patrick Galbraith
Removed DBUGs from
1362
            return(1);
1 by brian
clean slate
1363
          }
1364
        }
1365
        else
1366
        {
1367
          if (error == HA_ERR_RECORD_IS_THE_SAME)
1368
          {
1369
            error= 0;
1370
            updated--;
1371
          }
1372
          /* non-transactional or transactional table got modified   */
1373
          /* either multi_update class' flag is raised in its branch */
1374
          if (table->file->has_transactions())
1375
            transactional_tables= 1;
1376
          else
1377
          {
1378
            trans_safe= 0;
520.1.22 by Brian Aker
Second pass of thd cleanup
1379
            session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
1380
          }
1381
        }
1382
      }
1383
    }
1384
    else
1385
    {
1386
      int error;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1387
      Table *tmp_table= tmp_tables[offset];
1 by brian
clean slate
1388
      /*
1389
       For updatable VIEW store rowid of the updated table and
1390
       rowids of tables used in the CHECK OPTION condition.
1391
      */
482 by Brian Aker
Remove uint.
1392
      uint32_t field_num= 0;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1393
      List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1394
      Table *tbl= table;
1 by brian
clean slate
1395
      do
1396
      {
1397
        tbl->file->position(tbl->record[0]);
629.3.7 by Kristian Nielsen
Remove last trace of Field_string.
1398
        Field_varstring *ref_field=
1399
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1400
        ref_field->store((char *)tbl->file->ref, tbl->file->ref_length,
1401
                         &my_charset_bin);
1 by brian
clean slate
1402
        field_num++;
1403
      } while ((tbl= tbl_it++));
1404
1405
      /* Store regular updated fields in the row. */
520.1.22 by Brian Aker
Second pass of thd cleanup
1406
      fill_record(session,
1 by brian
clean slate
1407
                  tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1408
                  *values_for_table[offset], 1);
1409
1410
      /* Write row, ignoring duplicated updates to a row */
1411
      error= tmp_table->file->ha_write_row(tmp_table->record[0]);
1412
      if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
1413
      {
1414
        if (error &&
520.1.22 by Brian Aker
Second pass of thd cleanup
1415
            create_myisam_from_heap(session, tmp_table,
1 by brian
clean slate
1416
                                         tmp_table_param[offset].start_recinfo,
1417
                                         &tmp_table_param[offset].recinfo,
1418
                                         error, 1))
1419
        {
1420
          do_update=0;
51.2.2 by Patrick Galbraith
Removed DBUGs from
1421
	  return(1);			// Not a table_is_full error
1 by brian
clean slate
1422
	}
1423
        found++;
1424
      }
1425
    }
1426
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1427
  return(0);
1 by brian
clean slate
1428
}
1429
1430
482 by Brian Aker
Remove uint.
1431
void multi_update::send_error(uint32_t errcode,const char *err)
1 by brian
clean slate
1432
{
1433
  /* First send error what ever it is ... */
1434
  my_error(errcode, MYF(0), err);
1435
}
1436
1437
1438
void multi_update::abort()
1439
{
1440
  /* the error was handled or nothing deleted and no side effects return */
1441
  if (error_handled ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1442
      (!session->transaction.stmt.modified_non_trans_table && !updated))
1 by brian
clean slate
1443
    return;
1444
  /*
1445
    If all tables that has been updated are trans safe then just do rollback.
1446
    If not attempt to do remaining updates.
1447
  */
1448
1449
  if (! trans_safe)
1450
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1451
    assert(session->transaction.stmt.modified_non_trans_table);
1 by brian
clean slate
1452
    if (do_update && table_count > 1)
1453
    {
1454
      /* Add warning here */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1455
      /*
1 by brian
clean slate
1456
         todo/fixme: do_update() is never called with the arg 1.
1457
         should it change the signature to become argless?
1458
      */
398.1.10 by Monty Taylor
Actually removed VOID() this time.
1459
      do_updates();
1 by brian
clean slate
1460
    }
1461
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1462
  if (session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
1463
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1464
    session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
1465
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1466
  assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1 by brian
clean slate
1467
}
1468
1469
1470
int multi_update::do_updates()
1471
{
327.2.4 by Brian Aker
Refactoring table.h
1472
  TableList *cur_table;
1 by brian
clean slate
1473
  int local_error= 0;
1474
  ha_rows org_updated;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1475
  Table *table, *tmp_table;
1476
  List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1477
1 by brian
clean slate
1478
  do_update= 0;					// Don't retry this function
1479
  if (!found)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1480
    return(0);
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1481
  for (list<TableList*>::iterator it= update_tables.begin(); 
1482
       it != update_tables.end(); 
1483
       ++it)
1 by brian
clean slate
1484
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1485
    cur_table= *it;
1 by brian
clean slate
1486
    bool can_compare_record;
482 by Brian Aker
Remove uint.
1487
    uint32_t offset= cur_table->shared;
1 by brian
clean slate
1488
1489
    table = cur_table->table;
1490
    if (table == table_to_update)
1491
      continue;					// Already updated
1492
    org_updated= updated;
1493
    tmp_table= tmp_tables[cur_table->shared];
1494
    tmp_table->file->extra(HA_EXTRA_CACHE);	// Change to read cache
1495
    (void) table->file->ha_rnd_init(0);
1496
    table->file->extra(HA_EXTRA_NO_CACHE);
1497
1498
    check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1499
    while(Table *tbl= check_opt_it++)
1 by brian
clean slate
1500
    {
1501
      if (tbl->file->ha_rnd_init(1))
1502
        goto err;
1503
      tbl->file->extra(HA_EXTRA_CACHE);
1504
    }
1505
1506
    /*
1507
      Setup copy functions to copy fields from temporary table
1508
    */
1509
    List_iterator_fast<Item> field_it(*fields_for_table[offset]);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1510
    Field **field= tmp_table->field +
1 by brian
clean slate
1511
                   1 + unupdated_check_opt_tables.elements; // Skip row pointers
1512
    Copy_field *copy_field_ptr= copy_field, *copy_field_end;
1513
    for ( ; *field ; field++)
1514
    {
1515
      Item_field *item= (Item_field* ) field_it++;
1516
      (copy_field_ptr++)->set(item->field, *field, 0);
1517
    }
1518
    copy_field_end=copy_field_ptr;
1519
1520
    if ((local_error = tmp_table->file->ha_rnd_init(1)))
1521
      goto err;
1522
1523
    can_compare_record= (!(table->file->ha_table_flags() &
1524
                           HA_PARTIAL_COLUMN_READ) ||
982.1.13 by Padraig O'Sullivan
Removed the isBitmapSubset method. Can perform the same operation using the
1525
                         ((*table->read_set & *table->write_set) == *table->write_set));
1 by brian
clean slate
1526
1527
    for (;;)
1528
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1529
      if (session->killed && trans_safe)
1 by brian
clean slate
1530
	goto err;
1531
      if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
1532
      {
1533
	if (local_error == HA_ERR_END_OF_FILE)
1534
	  break;
1535
	if (local_error == HA_ERR_RECORD_DELETED)
1536
	  continue;				// May happen on dup key
1537
	goto err;
1538
      }
1539
1540
      /* call rnd_pos() using rowids from temporary table */
1541
      check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1542
      Table *tbl= table;
482 by Brian Aker
Remove uint.
1543
      uint32_t field_num= 0;
1 by brian
clean slate
1544
      do
1545
      {
629.3.7 by Kristian Nielsen
Remove last trace of Field_string.
1546
        Field_varstring *ref_field=
1547
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1 by brian
clean slate
1548
        if((local_error=
1549
              tbl->file->rnd_pos(tbl->record[0],
629.3.7 by Kristian Nielsen
Remove last trace of Field_string.
1550
                                (unsigned char *) ref_field->ptr
1551
                                 + ref_field->length_bytes)))
1 by brian
clean slate
1552
          goto err;
1553
        field_num++;
1554
      } while((tbl= check_opt_it++));
1555
1556
      table->status|= STATUS_UPDATED;
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
1557
      table->storeRecord();
1 by brian
clean slate
1558
1559
      /* Copy data from temporary table to current table */
1560
      for (copy_field_ptr=copy_field;
1561
	   copy_field_ptr != copy_field_end;
1562
	   copy_field_ptr++)
1563
	(*copy_field_ptr->do_copy)(copy_field_ptr);
1564
355 by Brian Aker
More Table cleanup
1565
      if (!can_compare_record || table->compare_record())
1 by brian
clean slate
1566
      {
1567
	if ((local_error=table->file->ha_update_row(table->record[1],
1568
						    table->record[0])) &&
1569
            local_error != HA_ERR_RECORD_IS_THE_SAME)
1570
	{
1571
	  if (!ignore ||
1572
              table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
1573
	    goto err;
1574
	}
1575
        if (local_error != HA_ERR_RECORD_IS_THE_SAME)
1576
          updated++;
1577
        else
1578
          local_error= 0;
1579
      }
1580
    }
1581
1582
    if (updated != org_updated)
1583
    {
1584
      if (table->file->has_transactions())
1585
        transactional_tables= 1;
1586
      else
1587
      {
1588
        trans_safe= 0;				// Can't do safe rollback
520.1.22 by Brian Aker
Second pass of thd cleanup
1589
        session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
1590
      }
1591
    }
1592
    (void) table->file->ha_rnd_end();
1593
    (void) tmp_table->file->ha_rnd_end();
1594
    check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1595
    while (Table *tbl= check_opt_it++)
1 by brian
clean slate
1596
        tbl->file->ha_rnd_end();
1597
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1598
  return(0);
1 by brian
clean slate
1599
1600
err:
1601
  {
1602
    prepare_record_for_error_message(local_error, table);
1603
    table->file->print_error(local_error,MYF(ME_FATALERROR));
1604
  }
1605
1606
  (void) table->file->ha_rnd_end();
1607
  (void) tmp_table->file->ha_rnd_end();
1608
  check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1609
  while (Table *tbl= check_opt_it++)
1 by brian
clean slate
1610
      tbl->file->ha_rnd_end();
1611
1612
  if (updated != org_updated)
1613
  {
1614
    if (table->file->has_transactions())
1615
      transactional_tables= 1;
1616
    else
1617
    {
1618
      trans_safe= 0;
520.1.22 by Brian Aker
Second pass of thd cleanup
1619
      session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
1620
    }
1621
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1622
  return(1);
1 by brian
clean slate
1623
}
1624
1625
1626
/* out: 1 if error, 0 if success */
1627
1628
bool multi_update::send_eof()
1629
{
1630
  char buff[STRING_BUFFER_USUAL_SIZE];
151 by Brian Aker
Ulonglong to uint64_t
1631
  uint64_t id;
520.1.21 by Brian Aker
THD -> Session rename
1632
  Session::killed_state killed_status= Session::NOT_KILLED;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1633
520.1.22 by Brian Aker
Second pass of thd cleanup
1634
  session->set_proc_info("updating reference tables");
1 by brian
clean slate
1635
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1636
  /*
1 by brian
clean slate
1637
     Does updates for the last n - 1 tables, returns 0 if ok;
1638
     error takes into account killed status gained in do_updates()
1639
  */
1640
  int local_error = (table_count) ? do_updates() : 0;
1641
  /*
1642
    if local_error is not set ON until after do_updates() then
1643
    later carried out killing should not affect binlogging.
1644
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
1645
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
1646
  session->set_proc_info("end");
1 by brian
clean slate
1647
1648
  /*
1649
    Write the SQL statement to the binlog if we updated
1650
    rows and we succeeded or if we updated some non
1651
    transactional tables.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1652
1 by brian
clean slate
1653
    The query has to binlog because there's a modified non-transactional table
1654
    either from the query's list or via a stored routine: bug#13270,23333
1655
  */
1656
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1657
  assert(trans_safe || !updated ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1658
              session->transaction.stmt.modified_non_trans_table);
1659
  if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
1660
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1661
    if (session->transaction.stmt.modified_non_trans_table)
1662
      session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
1663
  }
1664
  if (local_error != 0)
56 by brian
Next pass of true/false update.
1665
    error_handled= true; // to force early leave from ::send_error()
1 by brian
clean slate
1666
1667
  if (local_error > 0) // if the above log write did not fail ...
1668
  {
1669
    /* Safety: If we haven't got an error before (can happen in do_updates) */
1670
    my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
1671
	       MYF(0));
836 by Brian Aker
Fixed session call from function to method.
1672
    return true;
1 by brian
clean slate
1673
  }
1674
520.1.22 by Brian Aker
Second pass of thd cleanup
1675
  id= session->arg_of_last_insert_id_function ?
1676
    session->first_successful_insert_id_in_prev_stmt : 0;
1 by brian
clean slate
1677
  sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
520.1.22 by Brian Aker
Second pass of thd cleanup
1678
	  (ulong) session->cuted_fields);
1679
  session->row_count_func=
1680
    (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
836 by Brian Aker
Fixed session call from function to method.
1681
  session->my_ok((ulong) session->row_count_func, id, buff);
1682
1683
  return false;
1 by brian
clean slate
1684
}