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