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