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