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