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