~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. */
1005.2.3 by Monty Taylor
Further reversion of P.
105
  bitmap_init(&unique_map, unique_map_buf, table->s->fields, false);
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
894
    /* We have to cleanup translation tables of views. */
327.2.4 by Brian Aker
Refactoring table.h
895
    for (TableList *tbl= table_list; tbl; tbl= tbl->next_global)
1 by brian
clean slate
896
      tbl->cleanup_items();
897
520.1.22 by Brian Aker
Second pass of thd cleanup
898
    close_tables_for_reopen(session, &table_list);
1 by brian
clean slate
899
    goto reopen_tables;
900
  }
901
902
  /*
903
    Check that we are not using table that we are updating, but we should
904
    skip all tables of UPDATE SELECT itself
905
  */
56 by brian
Next pass of true/false update.
906
  lex->select_lex.exclude_from_table_unique_test= true;
1 by brian
clean slate
907
  /* We only need SELECT privilege for columns in the values list */
908
  for (tl= leaves; tl; tl= tl->next_leaf)
909
  {
910
    if (tl->lock_type != TL_READ &&
911
        tl->lock_type != TL_READ_NO_INSERT)
912
    {
327.2.4 by Brian Aker
Refactoring table.h
913
      TableList *duplicate;
520.1.22 by Brian Aker
Second pass of thd cleanup
914
      if ((duplicate= unique_table(session, tl, table_list, 0)))
1 by brian
clean slate
915
      {
916
        update_non_unique_table_error(table_list, "UPDATE", duplicate);
836 by Brian Aker
Fixed session call from function to method.
917
        return true;
1 by brian
clean slate
918
      }
919
    }
920
  }
921
  /*
56 by brian
Next pass of true/false update.
922
    Set exclude_from_table_unique_test value back to false. It is needed for
1 by brian
clean slate
923
    further check in multi_update::prepare whether to use record cache.
924
  */
56 by brian
Next pass of true/false update.
925
  lex->select_lex.exclude_from_table_unique_test= false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
926
520.1.22 by Brian Aker
Second pass of thd cleanup
927
  if (session->fill_derived_tables() &&
1 by brian
clean slate
928
      mysql_handle_derived(lex, &mysql_derived_filling))
836 by Brian Aker
Fixed session call from function to method.
929
    return true;
1 by brian
clean slate
930
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
931
  return (false);
1 by brian
clean slate
932
}
933
934
935
/*
936
  Setup multi-update handling and call SELECT to do the join
937
*/
938
520.1.22 by Brian Aker
Second pass of thd cleanup
939
bool mysql_multi_update(Session *session,
327.2.4 by Brian Aker
Refactoring table.h
940
                        TableList *table_list,
1 by brian
clean slate
941
                        List<Item> *fields,
942
                        List<Item> *values,
943
                        COND *conds,
151 by Brian Aker
Ulonglong to uint64_t
944
                        uint64_t options,
1 by brian
clean slate
945
                        enum enum_duplicates handle_duplicates, bool ignore,
848 by Brian Aker
typdef class removal (just... use the name of the class).
946
                        Select_Lex_Unit *unit, Select_Lex *select_lex)
1 by brian
clean slate
947
{
948
  multi_update *result;
949
  bool res;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
950
1 by brian
clean slate
951
  if (!(result= new multi_update(table_list,
520.1.22 by Brian Aker
Second pass of thd cleanup
952
				 session->lex->select_lex.leaf_tables,
1 by brian
clean slate
953
				 fields, values,
954
				 handle_duplicates, ignore)))
836 by Brian Aker
Fixed session call from function to method.
955
    return true;
1 by brian
clean slate
956
520.1.22 by Brian Aker
Second pass of thd cleanup
957
  session->abort_on_warning= true;
1 by brian
clean slate
958
959
  List<Item> total_list;
520.1.22 by Brian Aker
Second pass of thd cleanup
960
  res= mysql_select(session, &select_lex->ref_pointer_array,
1 by brian
clean slate
961
                      table_list, select_lex->with_wild,
962
                      total_list,
327.2.3 by Brian Aker
Refactoring of class Table
963
                      conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
1 by brian
clean slate
964
                      options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
965
                      OPTION_SETUP_TABLES_DONE,
966
                      result, unit, select_lex);
520.1.22 by Brian Aker
Second pass of thd cleanup
967
  res|= session->is_error();
1 by brian
clean slate
968
  if (unlikely(res))
969
  {
970
    /* If we had a another error reported earlier then this will be ignored */
971
    result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
972
    result->abort();
973
  }
974
  delete result;
520.1.22 by Brian Aker
Second pass of thd cleanup
975
  session->abort_on_warning= 0;
836 by Brian Aker
Fixed session call from function to method.
976
  return false;
1 by brian
clean slate
977
}
978
979
327.2.4 by Brian Aker
Refactoring table.h
980
multi_update::multi_update(TableList *table_list,
981
			   TableList *leaves_list,
1 by brian
clean slate
982
			   List<Item> *field_list, List<Item> *value_list,
983
			   enum enum_duplicates handle_duplicates_arg,
984
                           bool ignore_arg)
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
985
  :all_tables(table_list), leaves(leaves_list),
1 by brian
clean slate
986
   tmp_tables(0), updated(0), found(0), fields(field_list),
987
   values(value_list), table_count(0), copy_field(0),
988
   handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
989
   transactional_tables(0), ignore(ignore_arg), error_handled(0)
990
{}
991
992
993
/*
994
  Connect fields with tables and create list of tables that are updated
995
*/
996
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
997
int multi_update::prepare(List<Item> &,
848 by Brian Aker
typdef class removal (just... use the name of the class).
998
                          Select_Lex_Unit *)
1 by brian
clean slate
999
{
327.2.4 by Brian Aker
Refactoring table.h
1000
  TableList *table_ref;
1 by brian
clean slate
1001
  table_map tables_to_update;
1002
  Item_field *item;
1003
  List_iterator_fast<Item> field_it(*fields);
1004
  List_iterator_fast<Item> value_it(*values);
482 by Brian Aker
Remove uint.
1005
  uint32_t i, max_fields;
1006
  uint32_t leaf_table_count= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1007
520.1.22 by Brian Aker
Second pass of thd cleanup
1008
  session->count_cuted_fields= CHECK_FIELD_WARN;
1009
  session->cuted_fields=0L;
1010
  session->set_proc_info("updating main table");
1 by brian
clean slate
1011
1012
  tables_to_update= get_table_map(fields);
1013
1014
  if (!tables_to_update)
1015
  {
1016
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
51.2.2 by Patrick Galbraith
Removed DBUGs from
1017
    return(1);
1 by brian
clean slate
1018
  }
1019
1020
  /*
1021
    We have to check values after setup_tables to get covering_keys right in
1022
    reference tables
1023
  */
1024
520.1.22 by Brian Aker
Second pass of thd cleanup
1025
  if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1026
    return(1);
1 by brian
clean slate
1027
1028
  /*
1029
    Save tables beeing updated in update_tables
1030
    update_table->shared is position for table
1031
    Don't use key read on tables that are updated
1032
  */
1033
  for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1034
  {
1035
    /* 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
1036
    Table *table=table_ref->table;
1 by brian
clean slate
1037
    leaf_table_count++;
1038
    if (tables_to_update & table->map)
1039
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1040
      TableList *tl= (TableList*) session->memdup((char*) table_ref,
1 by brian
clean slate
1041
						sizeof(*tl));
1042
      if (!tl)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1043
	return(1);
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1044
      update_tables.push_back(tl);
1 by brian
clean slate
1045
      tl->shared= table_count++;
1046
      table->no_keyread=1;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1047
      table->covering_keys.reset();
1 by brian
clean slate
1048
      table->pos_in_table_list= tl;
1049
    }
1050
  }
1051
1052
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1053
  table_count=  update_tables.size();
1 by brian
clean slate
1054
520.1.22 by Brian Aker
Second pass of thd cleanup
1055
  tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1056
  tmp_table_param = (Tmp_Table_Param*) session->calloc(sizeof(Tmp_Table_Param) *
1 by brian
clean slate
1057
						   table_count);
520.1.22 by Brian Aker
Second pass of thd cleanup
1058
  fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1059
					      table_count);
1060
  values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1061
					      table_count);
1062
  if (session->is_fatal_error)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1063
    return(1);
1 by brian
clean slate
1064
  for (i=0 ; i < table_count ; i++)
1065
  {
1066
    fields_for_table[i]= new List_item;
1067
    values_for_table[i]= new List_item;
1068
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1069
  if (session->is_fatal_error)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1070
    return(1);
1 by brian
clean slate
1071
1072
  /* Split fields into fields_for_table[] and values_by_table[] */
1073
1074
  while ((item= (Item_field *) field_it++))
1075
  {
1076
    Item *value= value_it++;
482 by Brian Aker
Remove uint.
1077
    uint32_t offset= item->field->table->pos_in_table_list->shared;
1 by brian
clean slate
1078
    fields_for_table[offset]->push_back(item);
1079
    values_for_table[offset]->push_back(value);
1080
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
1081
  if (session->is_fatal_error)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1082
    return(1);
1 by brian
clean slate
1083
1084
  /* Allocate copy fields */
1085
  max_fields=0;
1086
  for (i=0 ; i < table_count ; i++)
1087
    set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
1088
  copy_field= new Copy_field[max_fields];
520.1.22 by Brian Aker
Second pass of thd cleanup
1089
  return(session->is_fatal_error != 0);
1 by brian
clean slate
1090
}
1091
1092
1093
/*
1094
  Check if table is safe to update on fly
1095
1096
  SYNOPSIS
1097
    safe_update_on_fly()
520.1.22 by Brian Aker
Second pass of thd cleanup
1098
    session                 Thread handler
1 by brian
clean slate
1099
    join_tab            How table is used in join
1100
    all_tables          List of tables
1101
1102
  NOTES
1103
    We can update the first table in join on the fly if we know that
1104
    a row in this table will never be read twice. This is true under
1105
    the following conditions:
1106
1107
    - We are doing a table scan and the data is in a separate file (MyISAM) or
1108
      if we don't update a clustered key.
1109
1110
    - We are doing a range scan and we don't update the scan key or
1111
      the primary key for a clustered table handler.
1112
1113
    - Table is not joined to itself.
1114
1115
    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
1116
    the Table::write_set bitmap.
1 by brian
clean slate
1117
1118
  WARNING
1119
    This code is a bit dependent of how make_join_readinfo() works.
1120
1121
  RETURN
1122
    0		Not safe to update
1123
    1		Safe to update
1124
*/
1125
520.1.22 by Brian Aker
Second pass of thd cleanup
1126
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
327.2.4 by Brian Aker
Refactoring table.h
1127
                               TableList *table_ref, TableList *all_tables)
1 by brian
clean slate
1128
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1129
  Table *table= join_tab->table;
520.1.22 by Brian Aker
Second pass of thd cleanup
1130
  if (unique_table(session, table_ref, all_tables, 0))
1 by brian
clean slate
1131
    return 0;
1132
  switch (join_tab->type) {
1133
  case JT_SYSTEM:
1134
  case JT_CONST:
1135
  case JT_EQ_REF:
56 by brian
Next pass of true/false update.
1136
    return true;				// At most one matching row
1 by brian
clean slate
1137
  case JT_REF:
1138
  case JT_REF_OR_NULL:
1139
    return !is_key_used(table, join_tab->ref.key, table->write_set);
1140
  case JT_ALL:
1141
    /* If range search on index */
1142
    if (join_tab->quick)
1143
      return !join_tab->quick->is_keys_used(table->write_set);
1144
    /* If scanning in clustered key */
1145
    if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1146
	table->s->primary_key < MAX_KEY)
1147
      return !is_key_used(table, table->s->primary_key, table->write_set);
56 by brian
Next pass of true/false update.
1148
    return true;
1 by brian
clean slate
1149
  default:
1150
    break;					// Avoid compler warning
1151
  }
56 by brian
Next pass of true/false update.
1152
  return false;
1 by brian
clean slate
1153
1154
}
1155
1156
1157
/*
1158
  Initialize table for multi table
1159
1160
  IMPLEMENTATION
1161
    - Update first table in join on the fly, if possible
1162
    - Create temporary tables to store changed values for all other tables
1163
      that are updated (and main_table if the above doesn't hold).
1164
*/
1165
1166
bool
1167
multi_update::initialize_tables(JOIN *join)
1168
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1169
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1170
    return(1);
1 by brian
clean slate
1171
  main_table=join->join_tab->table;
1172
  table_to_update= 0;
1173
1174
  /* Any update has at least one pair (field, value) */
51.2.2 by Patrick Galbraith
Removed DBUGs from
1175
  assert(fields->elements);
1 by brian
clean slate
1176
1177
  /* 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
1178
  for (list<TableList*>::iterator it= update_tables.begin(); 
1179
       it != update_tables.end(); 
1180
       ++it)
1 by brian
clean slate
1181
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1182
    Table *table= (*it)->table;
1183
    uint32_t cnt= (*it)->shared;
1 by brian
clean slate
1184
    List<Item> temp_fields;
327.2.3 by Brian Aker
Refactoring of class Table
1185
    order_st     group;
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1186
    Tmp_Table_Param *tmp_param;
1 by brian
clean slate
1187
1188
    table->mark_columns_needed_for_update();
1189
    if (ignore)
1190
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1191
    if (table == main_table)			// First table in join
1192
    {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1193
      if (safe_update_on_fly(session, join->join_tab, (*it), all_tables))
1 by brian
clean slate
1194
      {
1195
	table_to_update= main_table;		// Update table on the fly
1196
	continue;
1197
      }
1198
    }
1199
    table->prepare_for_position();
1200
1201
    tmp_param= tmp_table_param+cnt;
1202
1203
    /*
1204
      Create a temporary table to store all fields that are changed for this
1205
      table. The first field in the temporary table is a pointer to the
1206
      original row so that we can find and update it. For the updatable
1207
      VIEW a few following fields are rowids of tables used in the CHECK
1208
      OPTION condition.
1209
    */
1210
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1211
    List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1212
    Table *tbl= table;
1 by brian
clean slate
1213
    do
1214
    {
241 by Brian Aker
First pass of CHAR removal.
1215
      Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1216
                                                  tbl->alias, tbl->s, &my_charset_bin);
1 by brian
clean slate
1217
      if (!field)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1218
        return(1);
1 by brian
clean slate
1219
      field->init(tbl);
1220
      /*
1221
        The field will be converted to varstring when creating tmp table if
1222
        table to be updated was created by mysql 4.1. Deny this.
1223
      */
1224
      Item_field *ifield= new Item_field((Field *) field);
1225
      if (!ifield)
51.2.2 by Patrick Galbraith
Removed DBUGs from
1226
         return(1);
1 by brian
clean slate
1227
      ifield->maybe_null= 0;
1228
      if (temp_fields.push_back(ifield))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1229
        return(1);
1 by brian
clean slate
1230
    } while ((tbl= tbl_it++));
1231
1232
    temp_fields.concat(fields_for_table[cnt]);
1233
1234
    /* 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().
1235
    memset(&group, 0, sizeof(group));
1 by brian
clean slate
1236
    group.asc= 1;
1237
    group.item= (Item**) temp_fields.head_ref();
1238
1239
    tmp_param->quick_group=1;
1240
    tmp_param->field_count=temp_fields.elements;
1241
    tmp_param->group_parts=1;
1242
    tmp_param->group_length= table->file->ref_length;
520.1.22 by Brian Aker
Second pass of thd cleanup
1243
    if (!(tmp_tables[cnt]=create_tmp_table(session,
1 by brian
clean slate
1244
					   tmp_param,
1245
					   temp_fields,
327.2.3 by Brian Aker
Refactoring of class Table
1246
					   (order_st*) &group, 0, 0,
1 by brian
clean slate
1247
					   TMP_TABLE_ALL_COLUMNS,
1248
					   HA_POS_ERROR,
1249
					   (char *) "")))
51.2.2 by Patrick Galbraith
Removed DBUGs from
1250
      return(1);
1 by brian
clean slate
1251
    tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
1252
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1253
  return(0);
1 by brian
clean slate
1254
}
1255
1256
1257
multi_update::~multi_update()
1258
{
327.2.4 by Brian Aker
Refactoring table.h
1259
  TableList *table;
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1260
  for (list<TableList*>::iterator it= update_tables.begin(); 
1261
       it != update_tables.end(); 
1262
       ++it)
1 by brian
clean slate
1263
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1264
    table= *it;
1 by brian
clean slate
1265
    table->table->no_keyread= table->table->no_cache= 0;
1266
    if (ignore)
1267
      table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1268
  }
1269
1270
  if (tmp_tables)
1271
  {
482 by Brian Aker
Remove uint.
1272
    for (uint32_t cnt = 0; cnt < table_count; cnt++)
1 by brian
clean slate
1273
    {
1274
      if (tmp_tables[cnt])
1275
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
1276
	tmp_tables[cnt]->free_tmp_table(session);
1 by brian
clean slate
1277
	tmp_table_param[cnt].cleanup();
1278
      }
1279
    }
1280
  }
1281
  if (copy_field)
1282
    delete [] copy_field;
520.1.22 by Brian Aker
Second pass of thd cleanup
1283
  session->count_cuted_fields= CHECK_FIELD_IGNORE;		// Restore this setting
77.1.45 by Monty Taylor
Warning fixes.
1284
  assert(trans_safe || !updated ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1285
              session->transaction.all.modified_non_trans_table);
1 by brian
clean slate
1286
}
1287
1288
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
1289
bool multi_update::send_data(List<Item> &)
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
  for (list<TableList*>::iterator it= update_tables.begin(); 
1292
       it != update_tables.end(); 
1293
       ++it)
1 by brian
clean slate
1294
  {
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
1295
    Table *table= (*it)->table;
1296
    uint32_t offset= (*it)->shared;
1 by brian
clean slate
1297
    /*
1298
      Check if we are using outer join and we didn't find the row
1299
      or if we have already updated this row in the previous call to this
1300
      function.
1301
1302
      The same row may be presented here several times in a join of type
1303
      UPDATE t1 FROM t1,t2 SET t1.a=t2.a
1304
1305
      In this case we will do the update for the first found row combination.
1306
      The join algorithm guarantees that we will not find the a row in
1307
      t1 several times.
1308
    */
1309
    if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
1310
      continue;
1311
1312
    /*
1313
      We can use compare_record() to optimize away updates if
1314
      the table handler is returning all columns OR if
1315
      if all updated columns are read
1316
    */
1317
    if (table == table_to_update)
1318
    {
1319
      bool can_compare_record;
1320
      can_compare_record= (!(table->file->ha_table_flags() &
1321
                             HA_PARTIAL_COLUMN_READ) ||
1005.2.3 by Monty Taylor
Further reversion of P.
1322
                           bitmap_is_subset(table->write_set,
1323
                                            table->read_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) ||
1005.2.3 by Monty Taylor
Further reversion of P.
1525
                         bitmap_is_subset(table->write_set,
1526
                                          table->read_set));
1 by brian
clean slate
1527
1528
    for (;;)
1529
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1530
      if (session->killed && trans_safe)
1 by brian
clean slate
1531
	goto err;
1532
      if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
1533
      {
1534
	if (local_error == HA_ERR_END_OF_FILE)
1535
	  break;
1536
	if (local_error == HA_ERR_RECORD_DELETED)
1537
	  continue;				// May happen on dup key
1538
	goto err;
1539
      }
1540
1541
      /* call rnd_pos() using rowids from temporary table */
1542
      check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1543
      Table *tbl= table;
482 by Brian Aker
Remove uint.
1544
      uint32_t field_num= 0;
1 by brian
clean slate
1545
      do
1546
      {
629.3.7 by Kristian Nielsen
Remove last trace of Field_string.
1547
        Field_varstring *ref_field=
1548
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1 by brian
clean slate
1549
        if((local_error=
1550
              tbl->file->rnd_pos(tbl->record[0],
629.3.7 by Kristian Nielsen
Remove last trace of Field_string.
1551
                                (unsigned char *) ref_field->ptr
1552
                                 + ref_field->length_bytes)))
1 by brian
clean slate
1553
          goto err;
1554
        field_num++;
1555
      } while((tbl= check_opt_it++));
1556
1557
      table->status|= STATUS_UPDATED;
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
1558
      table->storeRecord();
1 by brian
clean slate
1559
1560
      /* Copy data from temporary table to current table */
1561
      for (copy_field_ptr=copy_field;
1562
	   copy_field_ptr != copy_field_end;
1563
	   copy_field_ptr++)
1564
	(*copy_field_ptr->do_copy)(copy_field_ptr);
1565
355 by Brian Aker
More Table cleanup
1566
      if (!can_compare_record || table->compare_record())
1 by brian
clean slate
1567
      {
1568
	if ((local_error=table->file->ha_update_row(table->record[1],
1569
						    table->record[0])) &&
1570
            local_error != HA_ERR_RECORD_IS_THE_SAME)
1571
	{
1572
	  if (!ignore ||
1573
              table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
1574
	    goto err;
1575
	}
1576
        if (local_error != HA_ERR_RECORD_IS_THE_SAME)
1577
          updated++;
1578
        else
1579
          local_error= 0;
1580
      }
1581
    }
1582
1583
    if (updated != org_updated)
1584
    {
1585
      if (table->file->has_transactions())
1586
        transactional_tables= 1;
1587
      else
1588
      {
1589
        trans_safe= 0;				// Can't do safe rollback
520.1.22 by Brian Aker
Second pass of thd cleanup
1590
        session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
1591
      }
1592
    }
1593
    (void) table->file->ha_rnd_end();
1594
    (void) tmp_table->file->ha_rnd_end();
1595
    check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1596
    while (Table *tbl= check_opt_it++)
1 by brian
clean slate
1597
        tbl->file->ha_rnd_end();
1598
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1599
  return(0);
1 by brian
clean slate
1600
1601
err:
1602
  {
1603
    prepare_record_for_error_message(local_error, table);
1604
    table->file->print_error(local_error,MYF(ME_FATALERROR));
1605
  }
1606
1607
  (void) table->file->ha_rnd_end();
1608
  (void) tmp_table->file->ha_rnd_end();
1609
  check_opt_it.rewind();
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1610
  while (Table *tbl= check_opt_it++)
1 by brian
clean slate
1611
      tbl->file->ha_rnd_end();
1612
1613
  if (updated != org_updated)
1614
  {
1615
    if (table->file->has_transactions())
1616
      transactional_tables= 1;
1617
    else
1618
    {
1619
      trans_safe= 0;
520.1.22 by Brian Aker
Second pass of thd cleanup
1620
      session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
1621
    }
1622
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
1623
  return(1);
1 by brian
clean slate
1624
}
1625
1626
1627
/* out: 1 if error, 0 if success */
1628
1629
bool multi_update::send_eof()
1630
{
1631
  char buff[STRING_BUFFER_USUAL_SIZE];
151 by Brian Aker
Ulonglong to uint64_t
1632
  uint64_t id;
520.1.21 by Brian Aker
THD -> Session rename
1633
  Session::killed_state killed_status= Session::NOT_KILLED;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1634
520.1.22 by Brian Aker
Second pass of thd cleanup
1635
  session->set_proc_info("updating reference tables");
1 by brian
clean slate
1636
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1637
  /*
1 by brian
clean slate
1638
     Does updates for the last n - 1 tables, returns 0 if ok;
1639
     error takes into account killed status gained in do_updates()
1640
  */
1641
  int local_error = (table_count) ? do_updates() : 0;
1642
  /*
1643
    if local_error is not set ON until after do_updates() then
1644
    later carried out killing should not affect binlogging.
1645
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
1646
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
1647
  session->set_proc_info("end");
1 by brian
clean slate
1648
1649
  /*
1650
    Write the SQL statement to the binlog if we updated
1651
    rows and we succeeded or if we updated some non
1652
    transactional tables.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1653
1 by brian
clean slate
1654
    The query has to binlog because there's a modified non-transactional table
1655
    either from the query's list or via a stored routine: bug#13270,23333
1656
  */
1657
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1658
  assert(trans_safe || !updated ||
520.1.22 by Brian Aker
Second pass of thd cleanup
1659
              session->transaction.stmt.modified_non_trans_table);
1660
  if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
1661
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1662
    if (session->transaction.stmt.modified_non_trans_table)
1663
      session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
1664
  }
1665
  if (local_error != 0)
56 by brian
Next pass of true/false update.
1666
    error_handled= true; // to force early leave from ::send_error()
1 by brian
clean slate
1667
1668
  if (local_error > 0) // if the above log write did not fail ...
1669
  {
1670
    /* Safety: If we haven't got an error before (can happen in do_updates) */
1671
    my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
1672
	       MYF(0));
836 by Brian Aker
Fixed session call from function to method.
1673
    return true;
1 by brian
clean slate
1674
  }
1675
520.1.22 by Brian Aker
Second pass of thd cleanup
1676
  id= session->arg_of_last_insert_id_function ?
1677
    session->first_successful_insert_id_in_prev_stmt : 0;
1 by brian
clean slate
1678
  sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
520.1.22 by Brian Aker
Second pass of thd cleanup
1679
	  (ulong) session->cuted_fields);
1680
  session->row_count_func=
1681
    (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
836 by Brian Aker
Fixed session call from function to method.
1682
  session->my_ok((ulong) session->row_count_func, id, buff);
1683
1684
  return false;
1 by brian
clean slate
1685
}