~drizzle-developers/ubuntu/natty/drizzle/natty

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
/*
18
  Single table and multi table updates of tables.
19
  Multi-table updates were introduced by Sinisa & Monty
20
*/
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
21
#include "config.h"
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"
28
#include "drizzled/optimizer/range.h"
29
#include "drizzled/records.h"
30
#include "drizzled/internal/my_sys.h"
31
#include "drizzled/internal/iocache.h"
1 by brian
clean slate
32
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
33
#include <list>
34
35
using namespace std;
1273.3.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
36
37
namespace drizzled
38
{
1005.2.3 by Monty Taylor
Further reversion of P.
39
1 by brian
clean slate
40
/**
41
  Re-read record if more columns are needed for error message.
42
43
  If we got a duplicate key error, we want to write an error
44
  message containing the value of the duplicate key. If we do not have
1273.395.6 by Brian Aker
First pass in encapsulating row
45
  all fields of the key value in getInsertRecord(), we need to re-read the
1 by brian
clean slate
46
  record with a proper read_set.
47
48
  @param[in] error   error number
49
  @param[in] table   table
50
*/
51
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
52
static void prepare_record_for_error_message(int error, Table *table)
1 by brian
clean slate
53
{
54
  Field **field_p;
55
  Field *field;
482 by Brian Aker
Remove uint.
56
  uint32_t keynr;
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
57
  MyBitmap unique_map; /* Fields in offended unique. */
1005.2.3 by Monty Taylor
Further reversion of P.
58
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
59
1 by brian
clean slate
60
  /*
61
    Only duplicate key errors print the key value.
62
    If storage engine does always read all columns, we have the value alraedy.
63
  */
64
  if ((error != HA_ERR_FOUND_DUPP_KEY) ||
1233.1.4 by Brian Aker
Added:
65
      !(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)))
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
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)
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
73
    return;
1 by brian
clean slate
74
75
  /* Create unique_map with all fields used by that index. */
1273.277.10 by Brian Aker
keys and fields partial encapsulation.
76
  unique_map.init(unique_map_buf, table->getMutableShare()->sizeFields());
1 by brian
clean slate
77
  table->mark_columns_used_by_index_no_reset(keynr, &unique_map);
78
79
  /* Subtract read_set and write_set. */
1005.2.3 by Monty Taylor
Further reversion of P.
80
  bitmap_subtract(&unique_map, table->read_set);
81
  bitmap_subtract(&unique_map, table->write_set);
1 by brian
clean slate
82
83
  /*
84
    If the unique index uses columns that are neither in read_set
85
    nor in write_set, we must re-read the record.
86
    Otherwise no need to do anything.
87
  */
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
88
  if (unique_map.isClearAll())
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. */
1273.395.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. */
1005.2.3 by Monty Taylor
Further reversion of P.
94
  bitmap_union(table->read_set, &unique_map);
1208.3.2 by brian
Update for Cursor renaming.
95
  /* Read record that is identified by table->cursor->ref. */
1273.395.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. */
1273.277.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
  {
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
100
    if (unique_map.isBitSet(field->field_index))
1273.277.16 by Brian Aker
Merge in change to getTable() to private the field objects.
101
    {
1273.102.163 by Brian Aker
Rollup patch for hiding tableshare.
102
      field->copy_from_tmp(table->getShare()->rec_buff_length);
1273.277.16 by Brian Aker
Merge in change to getTable() to private the field objects.
103
    }
104
  }
105
1 by brian
clean slate
106
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
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
0.1.2 by Monty Taylor
Import upstream version 2010.03.1317
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,
482 by Brian Aker
Remove uint.
132
                 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.
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;
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
146
  optimizer::SqlSelect *select= NULL;
1273.102.127 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
0.1.2 by Monty Taylor
Import upstream version 2010.03.1317
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))
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
155
  {
156
    DRIZZLE_UPDATE_DONE(1, 0, 0);
1109.1.2 by Brian Aker
More from the table patch
157
    return 1;
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
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 */
1273.102.163 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))
1 by brian
clean slate
168
    goto abort;
169
170
  old_covering_keys= table->covering_keys;		// Keys used in WHERE
171
  /* Check the fields we are going to modify */
520.1.22 by Brian Aker
Second pass of thd cleanup
172
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
971.6.11 by Eric Day
Removed purecov messages.
173
    goto abort;
1 by brian
clean slate
174
  if (table->timestamp_field)
175
  {
176
    // Don't set timestamp column if this is modified
1009 by Brian Aker
Merge of Monty
177
    if (table->timestamp_field->isWriteSet())
1273.102.196 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
178
    {
1 by brian
clean slate
179
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1273.102.196 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
180
    }
1 by brian
clean slate
181
    else
182
    {
183
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
184
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
1273.102.196 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
185
      {
1005.2.12 by Monty Taylor
Moved some things to the API.
186
        table->setWriteSet(table->timestamp_field->field_index);
1273.102.196 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
187
      }
1 by brian
clean slate
188
    }
189
  }
190
520.1.22 by Brian Aker
Second pass of thd cleanup
191
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
1 by brian
clean slate
192
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
193
    free_underlaid_joins(session, select_lex);
971.6.11 by Eric Day
Removed purecov messages.
194
    goto abort;
1 by brian
clean slate
195
  }
196
197
  if (select_lex->inner_refs_list.elements &&
520.1.22 by Brian Aker
Second pass of thd cleanup
198
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
1 by brian
clean slate
199
  {
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
200
    DRIZZLE_UPDATE_DONE(1, 0, 0);
201
    return -1;
1 by brian
clean slate
202
  }
203
204
  if (conds)
205
  {
206
    Item::cond_result cond_value;
520.1.22 by Brian Aker
Second pass of thd cleanup
207
    conds= remove_eq_conds(session, conds, &cond_value);
1 by brian
clean slate
208
    if (cond_value == Item::COND_FALSE)
209
      limit= 0;                                   // Impossible WHERE
210
  }
211
212
  /*
213
    If a timestamp field settable on UPDATE is present then to avoid wrong
214
    update force the table handler to retrieve write-only fields to be able
215
    to compare records and detect data change.
216
  */
1233.1.4 by Brian Aker
Added:
217
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
1 by brian
clean slate
218
      table->timestamp_field &&
219
      (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
220
       table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
1273.102.196 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
221
  {
1005.2.3 by Monty Taylor
Further reversion of P.
222
    bitmap_union(table->read_set, table->write_set);
1273.102.196 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
223
  }
1 by brian
clean slate
224
  // 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<>
225
  table->covering_keys.reset();
1 by brian
clean slate
226
1208.3.2 by brian
Update for Cursor renaming.
227
  /* Update the table->cursor->stats.records number */
228
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1 by brian
clean slate
229
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
230
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
1 by brian
clean slate
231
  if (error || !limit ||
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
232
      (select && select->check_quick(session, false, limit)))
1 by brian
clean slate
233
  {
234
    delete select;
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
235
    /**
236
     * Resetting the Diagnostic area to prevent
237
     * lp bug# 439719
238
     */
239
    session->main_da.reset_diagnostics_area();
520.1.22 by Brian Aker
Second pass of thd cleanup
240
    free_underlaid_joins(session, select_lex);
1 by brian
clean slate
241
    if (error)
242
      goto abort;				// Error in where
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
243
    DRIZZLE_UPDATE_DONE(0, 0, 0);
836 by Brian Aker
Fixed session call from function to method.
244
    session->my_ok();				// No matching records
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
245
    return 0;
1 by brian
clean slate
246
  }
247
  if (!select && limit != HA_POS_ERROR)
248
  {
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
249
    if ((used_index= optimizer::get_index_for_order(table, order, limit)) != MAX_KEY)
56 by brian
Next pass of true/false update.
250
      need_sort= false;
1 by brian
clean slate
251
  }
252
  /* 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<>
253
  if (table->quick_keys.none())
1 by brian
clean slate
254
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
255
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
1 by brian
clean slate
256
  }
257
258
  table->mark_columns_needed_for_update();
259
260
  /* 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:
261
1 by brian
clean slate
262
  if (select && select->quick)
263
  {
264
    used_index= select->quick->index;
265
    used_key_is_modified= (!select->quick->unique_key_range() &&
266
                          select->quick->is_keys_used(table->write_set));
267
  }
268
  else
269
  {
270
    used_key_is_modified= 0;
271
    if (used_index == MAX_KEY)                  // no index for sort order
1208.3.2 by brian
Update for Cursor renaming.
272
      used_index= table->cursor->key_used_on_scan;
1 by brian
clean slate
273
    if (used_index != MAX_KEY)
274
      used_key_is_modified= is_key_used(table, used_index, table->write_set);
275
  }
276
277
278
  if (used_key_is_modified || order)
279
  {
280
    /*
281
      We can't update table directly;  We must first search after all
282
      matching rows before updating the table!
283
    */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
284
    if (used_index < MAX_KEY && old_covering_keys.test(used_index))
1 by brian
clean slate
285
    {
286
      table->key_read=1;
287
      table->mark_columns_used_by_index(used_index);
288
    }
289
    else
290
    {
291
      table->use_all_columns();
292
    }
293
294
    /* note: We avoid sorting avoid if we sort on the used index */
295
    if (order && (need_sort || used_key_is_modified))
296
    {
297
      /*
327.2.3 by Brian Aker
Refactoring of class Table
298
	Doing an order_st BY;  Let filesort find and sort the rows we are going
1 by brian
clean slate
299
	to update
300
        NOTE: filesort will call table->prepare_for_position()
301
      */
482 by Brian Aker
Remove uint.
302
      uint32_t         length= 0;
1273.480.1 by Brian Aker
Style on structure cleanup
303
      SortField  *sortorder;
1 by brian
clean slate
304
      ha_rows examined_rows;
305
1273.3.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
306
      table->sort.io_cache = new internal::IO_CACHE;
641.3.8 by Monty Taylor
Removed my_malloc from drizzled.
307
1 by brian
clean slate
308
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
309
          (table->sort.found_records= filesort(session, table, sortorder, length,
1 by brian
clean slate
310
                                               select, limit, 1,
311
                                               &examined_rows))
312
          == HA_POS_ERROR)
313
      {
314
	goto err;
315
      }
316
      /*
317
	Filesort has already found and selected the rows we want to update,
318
	so we don't need the where clause
319
      */
320
      delete select;
321
      select= 0;
322
    }
323
    else
324
    {
325
      /*
326
	We are doing a search on a key that is updated. In this case
327
	we go trough the matching rows, save a pointer to them and
328
	update these in a separate loop based on the pointer.
329
      */
330
1273.3.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
331
      internal::IO_CACHE tempfile;
1273.254.1 by Brian Aker
Updates for moving temporary directory.
332
      if (open_cached_file(&tempfile, drizzle_tmpdir.c_str(),TEMP_PREFIX,
1 by brian
clean slate
333
			   DISK_BUFFER_SIZE, MYF(MY_WME)))
334
	goto err;
335
336
      /* If quick select is used, initialize it before retrieving rows. */
337
      if (select && select->quick && select->quick->reset())
338
        goto err;
1208.3.2 by brian
Update for Cursor renaming.
339
      table->cursor->try_semi_consistent_read(1);
1 by brian
clean slate
340
341
      /*
342
        When we get here, we have one of the following options:
343
        A. used_index == MAX_KEY
344
           This means we should use full table scan, and start it with
345
           init_read_record call
346
        B. used_index != MAX_KEY
347
           B.1 quick select is used, start the scan with init_read_record
348
           B.2 quick select is not used, this is full index scan (with LIMIT)
349
               Full index scan must be started with init_read_record_idx
350
      */
351
352
      if (used_index == MAX_KEY || (select && select->quick))
1273.102.127 by Brian Aker
Code shuffle on ReadRecord
353
      {
354
        info.init_read_record(session, table, select, 0, true);
355
      }
1 by brian
clean slate
356
      else
1273.102.127 by Brian Aker
Code shuffle on ReadRecord
357
      {
1273.243.3 by Brian Aker
Additional function -> method for readrecord
358
        info.init_read_record_idx(session, table, 1, used_index);
1273.102.127 by Brian Aker
Code shuffle on ReadRecord
359
      }
1 by brian
clean slate
360
520.1.22 by Brian Aker
Second pass of thd cleanup
361
      session->set_proc_info("Searching rows for update");
1 by brian
clean slate
362
      ha_rows tmp_limit= limit;
363
520.1.22 by Brian Aker
Second pass of thd cleanup
364
      while (!(error=info.read_record(&info)) && !session->killed)
1 by brian
clean slate
365
      {
366
	if (!(select && select->skip_record()))
367
	{
1208.3.2 by brian
Update for Cursor renaming.
368
          if (table->cursor->was_semi_consistent_read())
1 by brian
clean slate
369
	    continue;  /* repeat the read of the same row if it still exists */
370
1273.395.6 by Brian Aker
First pass in encapsulating row
371
	  table->cursor->position(table->getInsertRecord());
1208.3.2 by brian
Update for Cursor renaming.
372
	  if (my_b_write(&tempfile,table->cursor->ref,
373
			 table->cursor->ref_length))
1 by brian
clean slate
374
	  {
971.6.11 by Eric Day
Removed purecov messages.
375
	    error=1;
376
	    break;
1 by brian
clean slate
377
	  }
378
	  if (!--limit && using_limit)
379
	  {
380
	    error= -1;
381
	    break;
382
	  }
383
	}
384
	else
1208.3.2 by brian
Update for Cursor renaming.
385
	  table->cursor->unlock_row();
1 by brian
clean slate
386
      }
520.1.22 by Brian Aker
Second pass of thd cleanup
387
      if (session->killed && !error)
1 by brian
clean slate
388
	error= 1;				// Aborted
389
      limit= tmp_limit;
1208.3.2 by brian
Update for Cursor renaming.
390
      table->cursor->try_semi_consistent_read(0);
1273.102.127 by Brian Aker
Code shuffle on ReadRecord
391
      info.end_read_record();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
392
1 by brian
clean slate
393
      /* Change select to use tempfile */
394
      if (select)
395
      {
396
	delete select->quick;
397
	if (select->free_cond)
398
	  delete select->cond;
399
	select->quick=0;
400
	select->cond=0;
401
      }
402
      else
403
      {
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
404
	select= new optimizer::SqlSelect;
1 by brian
clean slate
405
	select->head=table;
406
      }
1273.3.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
407
      if (reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
971.6.11 by Eric Day
Removed purecov messages.
408
	error=1;
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
409
      // Read row ptrs from this cursor
410
      memcpy(select->file, &tempfile, sizeof(tempfile));
1 by brian
clean slate
411
      if (error >= 0)
412
	goto err;
413
    }
414
    if (table->key_read)
415
      table->restore_column_maps_after_mark_index();
416
  }
417
418
  if (ignore)
1208.3.2 by brian
Update for Cursor renaming.
419
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
420
1 by brian
clean slate
421
  if (select && select->quick && select->quick->reset())
422
    goto err;
1208.3.2 by brian
Update for Cursor renaming.
423
  table->cursor->try_semi_consistent_read(1);
1273.102.127 by Brian Aker
Code shuffle on ReadRecord
424
  info.init_read_record(session, table, select, 0, true);
1 by brian
clean slate
425
426
  updated= found= 0;
685.4.1 by Jay Pipes
Enabled the null.test.
427
  /*
428
   * Per the SQL standard, inserting NULL into a NOT NULL
429
   * field requires an error to be thrown.
430
   *
431
   * @NOTE
432
   *
433
   * NULL check and handling occurs in field_conv.cc
434
   */
435
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
436
  session->cuted_fields= 0L;
520.1.22 by Brian Aker
Second pass of thd cleanup
437
  session->set_proc_info("Updating");
1 by brian
clean slate
438
1208.3.2 by brian
Update for Cursor renaming.
439
  transactional_table= table->cursor->has_transactions();
520.1.22 by Brian Aker
Second pass of thd cleanup
440
  session->abort_on_warning= test(!ignore);
1 by brian
clean slate
441
442
  /*
443
    Assure that we can use position()
444
    if we need to create an error message.
445
  */
1233.1.4 by Brian Aker
Added:
446
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
1 by brian
clean slate
447
    table->prepare_for_position();
448
449
  /*
450
    We can use compare_record() to optimize away updates if
451
    the table handler is returning all columns OR if
452
    if all updated columns are read
453
  */
1233.1.4 by Brian Aker
Added:
454
  can_compare_record= (!(table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
1005.2.3 by Monty Taylor
Further reversion of P.
455
                       bitmap_is_subset(table->write_set, table->read_set));
1 by brian
clean slate
456
520.1.22 by Brian Aker
Second pass of thd cleanup
457
  while (!(error=info.read_record(&info)) && !session->killed)
1 by brian
clean slate
458
  {
459
    if (!(select && select->skip_record()))
460
    {
1208.3.2 by brian
Update for Cursor renaming.
461
      if (table->cursor->was_semi_consistent_read())
1 by brian
clean slate
462
        continue;  /* repeat the read of the same row if it still exists */
463
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
464
      table->storeRecord();
1235.1.11 by Brian Aker
Small cleanups, did in MERGE table only engine flag.
465
      if (fill_record(session, fields, values))
971.6.11 by Eric Day
Removed purecov messages.
466
        break;
1 by brian
clean slate
467
468
      found++;
469
355 by Brian Aker
More Table cleanup
470
      if (!can_compare_record || table->compare_record())
1 by brian
clean slate
471
      {
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
472
        /* Non-batched update */
1273.395.6 by Brian Aker
First pass in encapsulating row
473
        error= table->cursor->updateRecord(table->getUpdateRecord(),
474
                                            table->getInsertRecord());
1273.250.3 by Brian Aker
Fixes the assertion bug on handling of auto increment (sort of worthless,
475
476
        table->auto_increment_field_not_null= false;
477
1 by brian
clean slate
478
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
479
	{
480
          if (error != HA_ERR_RECORD_IS_THE_SAME)
481
            updated++;
482
          else
483
            error= 0;
484
	}
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
485
	else if (! ignore ||
1208.3.2 by brian
Update for Cursor renaming.
486
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
1 by brian
clean slate
487
	{
488
          /*
489
            If (ignore && error is ignorable) we don't have to
490
            do anything; otherwise...
491
          */
492
          myf flags= 0;
493
1208.3.2 by brian
Update for Cursor renaming.
494
          if (table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
1 by brian
clean slate
495
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
496
497
          prepare_record_for_error_message(error, table);
1216.1.1 by Brian Aker
Move print_error up to Engine.
498
	  table->print_error(error,MYF(flags));
1 by brian
clean slate
499
	  error= 1;
500
	  break;
501
	}
502
      }
503
504
      if (!--limit && using_limit)
505
      {
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
506
        error= -1;				// Simulate end of cursor
507
        break;
1 by brian
clean slate
508
      }
509
    }
510
    else
1208.3.2 by brian
Update for Cursor renaming.
511
      table->cursor->unlock_row();
520.1.22 by Brian Aker
Second pass of thd cleanup
512
    session->row_count++;
1 by brian
clean slate
513
  }
514
  dup_key_found= 0;
515
  /*
516
    Caching the killed status to pass as the arg to query event constuctor;
517
    The cached value can not change whereas the killed status can
518
    (externally) since this point and change of the latter won't affect
519
    binlogging.
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
520
    It's assumed that if an error was set in combination with an effective
1 by brian
clean slate
521
    killed status then the error is due to killing.
522
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
523
  killed_status= session->killed; // get the status of the volatile
1 by brian
clean slate
524
  // simulated killing after the loop must be ineffective for binlogging
520.1.21 by Brian Aker
THD -> Session rename
525
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
526
1235.1.9 by Brian Aker
Remove code around update batch handler (we have no engines supporting
527
  updated-= dup_key_found;
1208.3.2 by brian
Update for Cursor renaming.
528
  table->cursor->try_semi_consistent_read(0);
1 by brian
clean slate
529
530
  if (!transactional_table && updated > 0)
1273.2.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
531
    session->transaction.stmt.markModifiedNonTransData();
1 by brian
clean slate
532
1273.102.127 by Brian Aker
Code shuffle on ReadRecord
533
  info.end_read_record();
1 by brian
clean slate
534
  delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
535
  session->set_proc_info("end");
1208.3.2 by brian
Update for Cursor renaming.
536
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1 by brian
clean slate
537
538
  /*
539
    error < 0 means really no error at all: we processed all rows until the
540
    last one without error. error > 0 means an error (e.g. unique key
541
    violation and no IGNORE or REPLACE). error == 0 is also an error (if
542
    preparing the record or invoking before triggers fails). See
1273.121.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
543
    autocommitOrRollback(error>=0) and return(error>=0) below.
1 by brian
clean slate
544
    Sometimes we want to binlog even if we updated no rows, in case user used
545
    it to be sure master and slave are in same state.
546
  */
1273.2.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
547
  if ((error < 0) || session->transaction.stmt.hasModifiedNonTransData())
1 by brian
clean slate
548
  {
1273.2.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
549
    if (session->transaction.stmt.hasModifiedNonTransData())
550
      session->transaction.all.markModifiedNonTransData();
1 by brian
clean slate
551
  }
1273.2.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
552
  assert(transactional_table || !updated || session->transaction.stmt.hasModifiedNonTransData());
520.1.22 by Brian Aker
Second pass of thd cleanup
553
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
554
555
  /* If LAST_INSERT_ID(X) was used, report X */
520.1.22 by Brian Aker
Second pass of thd cleanup
556
  id= session->arg_of_last_insert_id_function ?
557
    session->first_successful_insert_id_in_prev_stmt : 0;
1 by brian
clean slate
558
559
  if (error < 0)
560
  {
561
    char buff[STRING_BUFFER_USUAL_SIZE];
0.1.5 by Monty Taylor
Import upstream version 2010.04.1513
562
    snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
520.1.22 by Brian Aker
Second pass of thd cleanup
563
	    (ulong) session->cuted_fields);
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
564
    session->row_count_func= updated;
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
565
    /**
566
     * Resetting the Diagnostic area to prevent
567
     * lp bug# 439719
568
     */
569
    session->main_da.reset_diagnostics_area();
971.3.59 by Eric Day
Removed client_capabilities from session and pushed functionality into protocol plugin.
570
    session->my_ok((ulong) session->row_count_func, found, id, buff);
0.1.10 by Monty Taylor
Import upstream version 2010.07.1666
571
    session->status_var.updated_row_count+= session->row_count_func;
1 by brian
clean slate
572
  }
1273.320.8 by Brian Aker
Update for count_cuted_fields.
573
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;		/* calc cuted fields */
520.1.22 by Brian Aker
Second pass of thd cleanup
574
  session->abort_on_warning= 0;
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
575
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
576
  return ((error >= 0 || session->is_error()) ? 1 : 0);
1 by brian
clean slate
577
578
err:
579
  delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
580
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
581
  if (table->key_read)
582
  {
583
    table->key_read=0;
1208.3.2 by brian
Update for Cursor renaming.
584
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
1 by brian
clean slate
585
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
586
  session->abort_on_warning= 0;
1 by brian
clean slate
587
588
abort:
0.1.1 by Monty Taylor
Import upstream version 2010.01.1273
589
  DRIZZLE_UPDATE_DONE(1, 0, 0);
590
  return 1;
1 by brian
clean slate
591
}
592
593
/*
594
  Prepare items in UPDATE statement
595
596
  SYNOPSIS
597
    mysql_prepare_update()
520.1.22 by Brian Aker
Second pass of thd cleanup
598
    session			- thread handler
1 by brian
clean slate
599
    table_list		- global/local table list
600
    conds		- conditions
0.1.2 by Monty Taylor
Import upstream version 2010.03.1317
601
    order_num		- number of ORDER BY list entries
602
    order		- ORDER BY clause list
1 by brian
clean slate
603
604
  RETURN VALUE
56 by brian
Next pass of true/false update.
605
    false OK
606
    true  error
1 by brian
clean slate
607
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
608
bool mysql_prepare_update(Session *session, TableList *table_list,
482 by Brian Aker
Remove uint.
609
			 Item **conds, uint32_t order_num, order_st *order)
1 by brian
clean slate
610
{
611
  List<Item> all_fields;
846 by Brian Aker
Removing on typedeffed class.
612
  Select_Lex *select_lex= &session->lex->select_lex;
1 by brian
clean slate
613
520.1.22 by Brian Aker
Second pass of thd cleanup
614
  session->lex->allow_sum_func= 0;
1 by brian
clean slate
615
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
616
  if (setup_tables_and_check_access(session, &select_lex->context,
1 by brian
clean slate
617
                                    &select_lex->top_join_list,
618
                                    table_list,
619
                                    &select_lex->leaf_tables,
620
                                    false) ||
1109.1.5 by Brian Aker
More extraction from sql_base
621
      session->setup_conds(table_list, conds) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
622
      select_lex->setup_ref_array(session, order_num) ||
623
      setup_order(session, select_lex->ref_pointer_array,
1 by brian
clean slate
624
		  table_list, all_fields, all_fields, order))
836 by Brian Aker
Fixed session call from function to method.
625
    return true;
1 by brian
clean slate
626
627
  /* Check that we are not using table that we are updating in a sub select */
628
  {
327.2.4 by Brian Aker
Refactoring table.h
629
    TableList *duplicate;
1220.1.13 by Brian Aker
Remove mysql_lock_have_duplicate() (we don't have merge, and our partition
630
    if ((duplicate= unique_table(table_list, table_list->next_global)))
1 by brian
clean slate
631
    {
632
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
836 by Brian Aker
Fixed session call from function to method.
633
      return true;
1 by brian
clean slate
634
    }
635
  }
177.1.1 by brian
Removed dead code around prep.
636
836 by Brian Aker
Fixed session call from function to method.
637
  return false;
1 by brian
clean slate
638
}
1273.3.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
639
640
} /* namespace drizzled */