~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
*/
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
21
#include "drizzled/server_includes.h"
22
#include "drizzled/sql_select.h"
23
#include "drizzled/error.h"
24
#include "drizzled/probes.h"
25
#include "drizzled/sql_base.h"
26
#include "drizzled/field/timestamp.h"
27
#include "drizzled/sql_parse.h"
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
28
#include "drizzled/optimizer/range.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
29
#include "drizzled/records.h"
1 by brian
clean slate
30
997.4.1 by Padraig O'Sullivan
Removed 1 instance of SQL_LIST from the source base. Replaced it with
31
#include <list>
982.1.3 by Padraig O'Sullivan
Various small cleanups to numerous files to now have calls to the correct
32
33
using namespace std;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
34
using namespace drizzled;
1005.2.3 by Monty Taylor
Further reversion of P.
35
1 by brian
clean slate
36
/**
37
  Re-read record if more columns are needed for error message.
38
39
  If we got a duplicate key error, we want to write an error
40
  message containing the value of the duplicate key. If we do not have
41
  all fields of the key value in record[0], we need to re-read the
42
  record with a proper read_set.
43
44
  @param[in] error   error number
45
  @param[in] table   table
46
*/
47
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
48
static void prepare_record_for_error_message(int error, Table *table)
1 by brian
clean slate
49
{
50
  Field **field_p;
51
  Field *field;
482 by Brian Aker
Remove uint.
52
  uint32_t keynr;
1103.6.2 by Padraig O'Sullivan
Removing references to MY_BITMAP throughout the code base and updating calls
53
  MyBitmap unique_map; /* Fields in offended unique. */
1005.2.3 by Monty Taylor
Further reversion of P.
54
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
55
1 by brian
clean slate
56
  /*
57
    Only duplicate key errors print the key value.
58
    If storage engine does always read all columns, we have the value alraedy.
59
  */
60
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
1233.1.4 by Brian Aker
Added:
61
      !(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
51.2.2 by Patrick Galbraith
Removed DBUGs from
62
    return;
1 by brian
clean slate
63
64
  /*
65
    Get the number of the offended index.
66
    We will see MAX_KEY if the engine cannot determine the affected index.
67
  */
1216.1.1 by Brian Aker
Move print_error up to Engine.
68
  if ((keynr= table->get_dup_key(error)) >= MAX_KEY)
51.2.2 by Patrick Galbraith
Removed DBUGs from
69
    return;
1 by brian
clean slate
70
71
  /* Create unique_map with all fields used by that index. */
1103.6.2 by Padraig O'Sullivan
Removing references to MY_BITMAP throughout the code base and updating calls
72
  unique_map.init(unique_map_buf, table->s->fields);
1 by brian
clean slate
73
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
74
75
  /* Subtract read_set and write_set. */
1005.2.3 by Monty Taylor
Further reversion of P.
76
  bitmap_subtract(&unique_map, table->read_set);
77
  bitmap_subtract(&unique_map, table->write_set);
1 by brian
clean slate
78
79
  /*
80
    If the unique index uses columns that are neither in read_set
81
    nor in write_set, we must re-read the record.
82
    Otherwise no need to do anything.
83
  */
1103.6.2 by Padraig O'Sullivan
Removing references to MY_BITMAP throughout the code base and updating calls
84
  if (unique_map.isClearAll())
51.2.2 by Patrick Galbraith
Removed DBUGs from
85
    return;
1 by brian
clean slate
86
1208.3.2 by brian
Update for Cursor renaming.
87
  /* Get identifier of last read record into table->cursor->ref. */
88
  table->cursor->position(table->record[0]);
1 by brian
clean slate
89
  /* Add all fields used by unique index to read_set. */
1005.2.3 by Monty Taylor
Further reversion of P.
90
  bitmap_union(table->read_set, &unique_map);
1208.3.2 by brian
Update for Cursor renaming.
91
  /* Read record that is identified by table->cursor->ref. */
92
  (void) table->cursor->rnd_pos(table->record[1], table->cursor->ref);
1 by brian
clean slate
93
  /* Copy the newly read columns into the new record. */
94
  for (field_p= table->field; (field= *field_p); field_p++)
1103.6.2 by Padraig O'Sullivan
Removing references to MY_BITMAP throughout the code base and updating calls
95
    if (unique_map.isBitSet(field->field_index))
1 by brian
clean slate
96
      field->copy_from_tmp(table->s->rec_buff_length);
97
51.2.2 by Patrick Galbraith
Removed DBUGs from
98
  return;
1 by brian
clean slate
99
}
100
101
102
/*
103
  Process usual UPDATE
104
105
  SYNOPSIS
106
    mysql_update()
520.1.22 by Brian Aker
Second pass of thd cleanup
107
    session			thread handler
1 by brian
clean slate
108
    fields		fields for update
109
    values		values of fields for update
110
    conds		WHERE clause expression
327.2.3 by Brian Aker
Refactoring of class Table
111
    order_num		number of elemen in order_st BY clause
112
    order		order_st BY clause list
1 by brian
clean slate
113
    limit		limit clause
114
    handle_duplicates	how to handle duplicates
115
116
  RETURN
117
    0  - OK
118
    1  - error
119
*/
120
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
121
int mysql_update(Session *session, TableList *table_list,
122
                 List<Item> &fields, List<Item> &values, COND *conds,
482 by Brian Aker
Remove uint.
123
                 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.
124
                 ha_rows limit, enum enum_duplicates,
77.1.45 by Monty Taylor
Warning fixes.
125
                 bool ignore)
1 by brian
clean slate
126
{
127
  bool		using_limit= limit != HA_POS_ERROR;
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
128
  bool		used_key_is_modified;
129
  bool		transactional_table;
1 by brian
clean slate
130
  bool		can_compare_record;
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
131
  int		error;
1 by brian
clean slate
132
  uint		used_index= MAX_KEY, dup_key_found;
56 by brian
Next pass of true/false update.
133
  bool          need_sort= true;
1 by brian
clean slate
134
  ha_rows	updated, found;
135
  key_map	old_covering_keys;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
136
  Table		*table;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
137
  optimizer::SqlSelect *select= NULL;
1 by brian
clean slate
138
  READ_RECORD	info;
846 by Brian Aker
Removing on typedeffed class.
139
  Select_Lex    *select_lex= &session->lex->select_lex;
151 by Brian Aker
Ulonglong to uint64_t
140
  uint64_t     id;
1 by brian
clean slate
141
  List<Item> all_fields;
520.1.21 by Brian Aker
THD -> Session rename
142
  Session::killed_state killed_status= Session::NOT_KILLED;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
143
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
144
  DRIZZLE_UPDATE_START(session->query);
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
145
  if (session->openTablesLock(table_list))
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
146
  {
147
    DRIZZLE_UPDATE_DONE(1, 0, 0);
1109.1.2 by Brian Aker
More from the table patch
148
    return 1;
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
149
  }
1109.1.2 by Brian Aker
More from the table patch
150
520.1.22 by Brian Aker
Second pass of thd cleanup
151
  session->set_proc_info("init");
1 by brian
clean slate
152
  table= table_list->table;
153
154
  /* Calculate "table->covering_keys" based on the WHERE */
155
  table->covering_keys= table->s->keys_in_use;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
156
  table->quick_keys.reset();
1 by brian
clean slate
157
520.1.22 by Brian Aker
Second pass of thd cleanup
158
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
1 by brian
clean slate
159
    goto abort;
160
161
  old_covering_keys= table->covering_keys;		// Keys used in WHERE
162
  /* Check the fields we are going to modify */
520.1.22 by Brian Aker
Second pass of thd cleanup
163
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
971.6.11 by Eric Day
Removed purecov messages.
164
    goto abort;
1 by brian
clean slate
165
  if (table->timestamp_field)
166
  {
167
    // Don't set timestamp column if this is modified
1009 by Brian Aker
Merge of Monty
168
    if (table->timestamp_field->isWriteSet())
1 by brian
clean slate
169
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
170
    else
171
    {
172
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
173
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
1005.2.12 by Monty Taylor
Moved some things to the API.
174
        table->setWriteSet(table->timestamp_field->field_index);
1 by brian
clean slate
175
    }
176
  }
177
520.1.22 by Brian Aker
Second pass of thd cleanup
178
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
1 by brian
clean slate
179
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
180
    free_underlaid_joins(session, select_lex);
971.6.11 by Eric Day
Removed purecov messages.
181
    goto abort;
1 by brian
clean slate
182
  }
183
184
  if (select_lex->inner_refs_list.elements &&
520.1.22 by Brian Aker
Second pass of thd cleanup
185
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
1 by brian
clean slate
186
  {
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
187
    DRIZZLE_UPDATE_DONE(1, 0, 0);
188
    return -1;
1 by brian
clean slate
189
  }
190
191
  if (conds)
192
  {
193
    Item::cond_result cond_value;
520.1.22 by Brian Aker
Second pass of thd cleanup
194
    conds= remove_eq_conds(session, conds, &cond_value);
1 by brian
clean slate
195
    if (cond_value == Item::COND_FALSE)
196
      limit= 0;                                   // Impossible WHERE
197
  }
198
199
  /*
200
    If a timestamp field settable on UPDATE is present then to avoid wrong
201
    update force the table handler to retrieve write-only fields to be able
202
    to compare records and detect data change.
203
  */
1233.1.4 by Brian Aker
Added:
204
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
1 by brian
clean slate
205
      table->timestamp_field &&
206
      (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
207
       table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
1005.2.3 by Monty Taylor
Further reversion of P.
208
    bitmap_union(table->read_set, table->write_set);
1 by brian
clean slate
209
  // 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<>
210
  table->covering_keys.reset();
1 by brian
clean slate
211
1208.3.2 by brian
Update for Cursor renaming.
212
  /* Update the table->cursor->stats.records number */
213
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1 by brian
clean slate
214
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
215
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
1 by brian
clean slate
216
  if (error || !limit ||
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
217
      (select && select->check_quick(session, false, limit)))
1 by brian
clean slate
218
  {
219
    delete select;
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
220
    /**
221
     * Resetting the Diagnostic area to prevent
222
     * lp bug# 439719
223
     */
224
    session->main_da.reset_diagnostics_area();
520.1.22 by Brian Aker
Second pass of thd cleanup
225
    free_underlaid_joins(session, select_lex);
1 by brian
clean slate
226
    if (error)
227
      goto abort;				// Error in where
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
228
    DRIZZLE_UPDATE_DONE(0, 0, 0);
836 by Brian Aker
Fixed session call from function to method.
229
    session->my_ok();				// No matching records
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
230
    return 0;
1 by brian
clean slate
231
  }
232
  if (!select && limit != HA_POS_ERROR)
233
  {
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
234
    if ((used_index= optimizer::get_index_for_order(table, order, limit)) != MAX_KEY)
56 by brian
Next pass of true/false update.
235
      need_sort= false;
1 by brian
clean slate
236
  }
237
  /* 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<>
238
  if (table->quick_keys.none())
1 by brian
clean slate
239
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
240
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
1 by brian
clean slate
241
  }
242
243
  table->mark_columns_needed_for_update();
244
245
  /* 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:
246
1 by brian
clean slate
247
  if (select && select->quick)
248
  {
249
    used_index= select->quick->index;
250
    used_key_is_modified= (!select->quick->unique_key_range() &&
251
                          select->quick->is_keys_used(table->write_set));
252
  }
253
  else
254
  {
255
    used_key_is_modified= 0;
256
    if (used_index == MAX_KEY)                  // no index for sort order
1208.3.2 by brian
Update for Cursor renaming.
257
      used_index= table->cursor->key_used_on_scan;
1 by brian
clean slate
258
    if (used_index != MAX_KEY)
259
      used_key_is_modified= is_key_used(table, used_index, table->write_set);
260
  }
261
262
263
  if (used_key_is_modified || order)
264
  {
265
    /*
266
      We can't update table directly;  We must first search after all
267
      matching rows before updating the table!
268
    */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
269
    if (used_index < MAX_KEY && old_covering_keys.test(used_index))
1 by brian
clean slate
270
    {
271
      table->key_read=1;
272
      table->mark_columns_used_by_index(used_index);
273
    }
274
    else
275
    {
276
      table->use_all_columns();
277
    }
278
279
    /* note: We avoid sorting avoid if we sort on the used index */
280
    if (order && (need_sort || used_key_is_modified))
281
    {
282
      /*
327.2.3 by Brian Aker
Refactoring of class Table
283
	Doing an order_st BY;  Let filesort find and sort the rows we are going
1 by brian
clean slate
284
	to update
285
        NOTE: filesort will call table->prepare_for_position()
286
      */
482 by Brian Aker
Remove uint.
287
      uint32_t         length= 0;
1 by brian
clean slate
288
      SORT_FIELD  *sortorder;
289
      ha_rows examined_rows;
290
684 by Brian Aker
Mass cleanup for casting.
291
      table->sort.io_cache = new IO_CACHE;
641.3.8 by Monty Taylor
Removed my_malloc from drizzled.
292
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
293
1 by brian
clean slate
294
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
295
          (table->sort.found_records= filesort(session, table, sortorder, length,
1 by brian
clean slate
296
                                               select, limit, 1,
297
                                               &examined_rows))
298
          == HA_POS_ERROR)
299
      {
300
	goto err;
301
      }
302
      /*
303
	Filesort has already found and selected the rows we want to update,
304
	so we don't need the where clause
305
      */
306
      delete select;
307
      select= 0;
308
    }
309
    else
310
    {
311
      /*
312
	We are doing a search on a key that is updated. In this case
313
	we go trough the matching rows, save a pointer to them and
314
	update these in a separate loop based on the pointer.
315
      */
316
317
      IO_CACHE tempfile;
575.4.3 by ysano
Rename mysql to drizzle.
318
      if (open_cached_file(&tempfile, drizzle_tmpdir,TEMP_PREFIX,
1 by brian
clean slate
319
			   DISK_BUFFER_SIZE, MYF(MY_WME)))
320
	goto err;
321
322
      /* If quick select is used, initialize it before retrieving rows. */
323
      if (select && select->quick && select->quick->reset())
324
        goto err;
1208.3.2 by brian
Update for Cursor renaming.
325
      table->cursor->try_semi_consistent_read(1);
1 by brian
clean slate
326
327
      /*
328
        When we get here, we have one of the following options:
329
        A. used_index == MAX_KEY
330
           This means we should use full table scan, and start it with
331
           init_read_record call
332
        B. used_index != MAX_KEY
333
           B.1 quick select is used, start the scan with init_read_record
334
           B.2 quick select is not used, this is full index scan (with LIMIT)
335
               Full index scan must be started with init_read_record_idx
336
      */
337
338
      if (used_index == MAX_KEY || (select && select->quick))
520.1.22 by Brian Aker
Second pass of thd cleanup
339
        init_read_record(&info,session,table,select,0,1);
1 by brian
clean slate
340
      else
520.1.22 by Brian Aker
Second pass of thd cleanup
341
        init_read_record_idx(&info, session, table, 1, used_index);
1 by brian
clean slate
342
520.1.22 by Brian Aker
Second pass of thd cleanup
343
      session->set_proc_info("Searching rows for update");
1 by brian
clean slate
344
      ha_rows tmp_limit= limit;
345
520.1.22 by Brian Aker
Second pass of thd cleanup
346
      while (!(error=info.read_record(&info)) && !session->killed)
1 by brian
clean slate
347
      {
348
	if (!(select && select->skip_record()))
349
	{
1208.3.2 by brian
Update for Cursor renaming.
350
          if (table->cursor->was_semi_consistent_read())
1 by brian
clean slate
351
	    continue;  /* repeat the read of the same row if it still exists */
352
1208.3.2 by brian
Update for Cursor renaming.
353
	  table->cursor->position(table->record[0]);
354
	  if (my_b_write(&tempfile,table->cursor->ref,
355
			 table->cursor->ref_length))
1 by brian
clean slate
356
	  {
971.6.11 by Eric Day
Removed purecov messages.
357
	    error=1;
358
	    break;
1 by brian
clean slate
359
	  }
360
	  if (!--limit && using_limit)
361
	  {
362
	    error= -1;
363
	    break;
364
	  }
365
	}
366
	else
1208.3.2 by brian
Update for Cursor renaming.
367
	  table->cursor->unlock_row();
1 by brian
clean slate
368
      }
520.1.22 by Brian Aker
Second pass of thd cleanup
369
      if (session->killed && !error)
1 by brian
clean slate
370
	error= 1;				// Aborted
371
      limit= tmp_limit;
1208.3.2 by brian
Update for Cursor renaming.
372
      table->cursor->try_semi_consistent_read(0);
1 by brian
clean slate
373
      end_read_record(&info);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
374
1 by brian
clean slate
375
      /* Change select to use tempfile */
376
      if (select)
377
      {
378
	delete select->quick;
379
	if (select->free_cond)
380
	  delete select->cond;
381
	select->quick=0;
382
	select->cond=0;
383
      }
384
      else
385
      {
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
386
	select= new optimizer::SqlSelect;
1 by brian
clean slate
387
	select->head=table;
388
      }
389
      if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
971.6.11 by Eric Day
Removed purecov messages.
390
	error=1;
1208.3.2 by brian
Update for Cursor renaming.
391
      select->file= tempfile;			// Read row ptrs from this cursor
1 by brian
clean slate
392
      if (error >= 0)
393
	goto err;
394
    }
395
    if (table->key_read)
396
      table->restore_column_maps_after_mark_index();
397
  }
398
399
  if (ignore)
1208.3.2 by brian
Update for Cursor renaming.
400
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
401
1 by brian
clean slate
402
  if (select && select->quick && select->quick->reset())
403
    goto err;
1208.3.2 by brian
Update for Cursor renaming.
404
  table->cursor->try_semi_consistent_read(1);
520.1.22 by Brian Aker
Second pass of thd cleanup
405
  init_read_record(&info,session,table,select,0,1);
1 by brian
clean slate
406
407
  updated= found= 0;
685.4.1 by Jay Pipes
Enabled the null.test.
408
  /*
409
   * Per the SQL standard, inserting NULL into a NOT NULL
410
   * field requires an error to be thrown.
411
   *
412
   * @NOTE
413
   *
414
   * NULL check and handling occurs in field_conv.cc
415
   */
416
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
417
  session->cuted_fields= 0L;
520.1.22 by Brian Aker
Second pass of thd cleanup
418
  session->set_proc_info("Updating");
1 by brian
clean slate
419
1208.3.2 by brian
Update for Cursor renaming.
420
  transactional_table= table->cursor->has_transactions();
520.1.22 by Brian Aker
Second pass of thd cleanup
421
  session->abort_on_warning= test(!ignore);
1 by brian
clean slate
422
423
  /*
424
    Assure that we can use position()
425
    if we need to create an error message.
426
  */
1233.1.4 by Brian Aker
Added:
427
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
1 by brian
clean slate
428
    table->prepare_for_position();
429
430
  /*
431
    We can use compare_record() to optimize away updates if
432
    the table handler is returning all columns OR if
433
    if all updated columns are read
434
  */
1233.1.4 by Brian Aker
Added:
435
  can_compare_record= (!(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
1005.2.3 by Monty Taylor
Further reversion of P.
436
                       bitmap_is_subset(table->write_set, table->read_set));
1 by brian
clean slate
437
520.1.22 by Brian Aker
Second pass of thd cleanup
438
  while (!(error=info.read_record(&info)) && !session->killed)
1 by brian
clean slate
439
  {
440
    if (!(select && select->skip_record()))
441
    {
1208.3.2 by brian
Update for Cursor renaming.
442
      if (table->cursor->was_semi_consistent_read())
1 by brian
clean slate
443
        continue;  /* repeat the read of the same row if it still exists */
444
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
445
      table->storeRecord();
1235.1.11 by Brian Aker
Small cleanups, did in MERGE table only engine flag.
446
      if (fill_record(session, fields, values))
971.6.11 by Eric Day
Removed purecov messages.
447
        break;
1 by brian
clean slate
448
449
      found++;
450
355 by Brian Aker
More Table cleanup
451
      if (!can_compare_record || table->compare_record())
1 by brian
clean slate
452
      {
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
453
        /* Non-batched update */
454
        error= table->cursor->ha_update_row(table->record[1],
1 by brian
clean slate
455
                                            table->record[0]);
456
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
457
	{
458
          if (error != HA_ERR_RECORD_IS_THE_SAME)
459
            updated++;
460
          else
461
            error= 0;
462
	}
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
463
	else if (! ignore ||
1208.3.2 by brian
Update for Cursor renaming.
464
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
1 by brian
clean slate
465
	{
466
          /*
467
            If (ignore && error is ignorable) we don't have to
468
            do anything; otherwise...
469
          */
470
          myf flags= 0;
471
1208.3.2 by brian
Update for Cursor renaming.
472
          if (table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
1 by brian
clean slate
473
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
474
475
          prepare_record_for_error_message(error, table);
1216.1.1 by Brian Aker
Move print_error up to Engine.
476
	  table->print_error(error,MYF(flags));
1 by brian
clean slate
477
	  error= 1;
478
	  break;
479
	}
480
      }
481
482
      if (!--limit && using_limit)
483
      {
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
484
        error= -1;				// Simulate end of cursor
485
        break;
1 by brian
clean slate
486
      }
487
    }
488
    else
1208.3.2 by brian
Update for Cursor renaming.
489
      table->cursor->unlock_row();
520.1.22 by Brian Aker
Second pass of thd cleanup
490
    session->row_count++;
1 by brian
clean slate
491
  }
492
  dup_key_found= 0;
493
  /*
494
    Caching the killed status to pass as the arg to query event constuctor;
495
    The cached value can not change whereas the killed status can
496
    (externally) since this point and change of the latter won't affect
497
    binlogging.
51.2.2 by Patrick Galbraith
Removed DBUGs from
498
    It's assumed that if an error was set in combination with an effective
1 by brian
clean slate
499
    killed status then the error is due to killing.
500
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
501
  killed_status= session->killed; // get the status of the volatile
1 by brian
clean slate
502
  // simulated killing after the loop must be ineffective for binlogging
520.1.21 by Brian Aker
THD -> Session rename
503
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
51.2.2 by Patrick Galbraith
Removed DBUGs from
504
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
505
  updated-= dup_key_found;
1208.3.2 by brian
Update for Cursor renaming.
506
  table->cursor->try_semi_consistent_read(0);
1 by brian
clean slate
507
508
  if (!transactional_table && updated > 0)
520.1.22 by Brian Aker
Second pass of thd cleanup
509
    session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
510
511
  end_read_record(&info);
512
  delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
513
  session->set_proc_info("end");
1208.3.2 by brian
Update for Cursor renaming.
514
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1 by brian
clean slate
515
516
  /*
517
    error < 0 means really no error at all: we processed all rows until the
518
    last one without error. error > 0 means an error (e.g. unique key
519
    violation and no IGNORE or REPLACE). error == 0 is also an error (if
520
    preparing the record or invoking before triggers fails). See
51.2.2 by Patrick Galbraith
Removed DBUGs from
521
    ha_autocommit_or_rollback(error>=0) and return(error>=0) below.
1 by brian
clean slate
522
    Sometimes we want to binlog even if we updated no rows, in case user used
523
    it to be sure master and slave are in same state.
524
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
525
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
526
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
527
    if (session->transaction.stmt.modified_non_trans_table)
528
      session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
529
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
530
  assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
531
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
532
533
  /* If LAST_INSERT_ID(X) was used, report X */
520.1.22 by Brian Aker
Second pass of thd cleanup
534
  id= session->arg_of_last_insert_id_function ?
535
    session->first_successful_insert_id_in_prev_stmt : 0;
1 by brian
clean slate
536
537
  if (error < 0)
538
  {
539
    char buff[STRING_BUFFER_USUAL_SIZE];
540
    sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
520.1.22 by Brian Aker
Second pass of thd cleanup
541
	    (ulong) session->cuted_fields);
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
542
    session->row_count_func= updated;
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
543
    /**
544
     * Resetting the Diagnostic area to prevent
545
     * lp bug# 439719
546
     */
547
    session->main_da.reset_diagnostics_area();
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
548
    session->my_ok((ulong) session->row_count_func, found, id, buff);
1 by brian
clean slate
549
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
550
  session->count_cuted_fields= CHECK_FIELD_IGNORE;		/* calc cuted fields */
551
  session->abort_on_warning= 0;
1126.10.25 by Padraig O'Sullivan
Updated calls to some dtrace probes to cast the parameter to const char *
552
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
553
  return ((error >= 0 || session->is_error()) ? 1 : 0);
1 by brian
clean slate
554
555
err:
556
  delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
557
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
558
  if (table->key_read)
559
  {
560
    table->key_read=0;
1208.3.2 by brian
Update for Cursor renaming.
561
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
1 by brian
clean slate
562
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
563
  session->abort_on_warning= 0;
1 by brian
clean slate
564
565
abort:
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
566
  DRIZZLE_UPDATE_DONE(1, 0, 0);
567
  return 1;
1 by brian
clean slate
568
}
569
570
/*
571
  Prepare items in UPDATE statement
572
573
  SYNOPSIS
574
    mysql_prepare_update()
520.1.22 by Brian Aker
Second pass of thd cleanup
575
    session			- thread handler
1 by brian
clean slate
576
    table_list		- global/local table list
577
    conds		- conditions
327.2.3 by Brian Aker
Refactoring of class Table
578
    order_num		- number of order_st BY list entries
579
    order		- order_st BY clause list
1 by brian
clean slate
580
581
  RETURN VALUE
56 by brian
Next pass of true/false update.
582
    false OK
583
    true  error
1 by brian
clean slate
584
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
585
bool mysql_prepare_update(Session *session, TableList *table_list,
482 by Brian Aker
Remove uint.
586
			 Item **conds, uint32_t order_num, order_st *order)
1 by brian
clean slate
587
{
588
  List<Item> all_fields;
846 by Brian Aker
Removing on typedeffed class.
589
  Select_Lex *select_lex= &session->lex->select_lex;
1 by brian
clean slate
590
520.1.22 by Brian Aker
Second pass of thd cleanup
591
  session->lex->allow_sum_func= 0;
1 by brian
clean slate
592
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
593
  if (setup_tables_and_check_access(session, &select_lex->context,
1 by brian
clean slate
594
                                    &select_lex->top_join_list,
595
                                    table_list,
596
                                    &select_lex->leaf_tables,
597
                                    false) ||
1109.1.5 by Brian Aker
More extraction from sql_base
598
      session->setup_conds(table_list, conds) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
599
      select_lex->setup_ref_array(session, order_num) ||
600
      setup_order(session, select_lex->ref_pointer_array,
1 by brian
clean slate
601
		  table_list, all_fields, all_fields, order))
836 by Brian Aker
Fixed session call from function to method.
602
    return true;
1 by brian
clean slate
603
604
  /* Check that we are not using table that we are updating in a sub select */
605
  {
327.2.4 by Brian Aker
Refactoring table.h
606
    TableList *duplicate;
1220.1.13 by Brian Aker
Remove mysql_lock_have_duplicate() (we don't have merge, and our partition
607
    if ((duplicate= unique_table(table_list, table_list->next_global)))
1 by brian
clean slate
608
    {
609
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
836 by Brian Aker
Fixed session call from function to method.
610
      return true;
1 by brian
clean slate
611
    }
612
  }
177.1.1 by brian
Removed dead code around prep.
613
836 by Brian Aker
Fixed session call from function to method.
614
  return false;
1 by brian
clean slate
615
}