~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2010-10-19 21:58:26 UTC
  • mfrom: (1861.3.7 ld-version-script)
  • mto: This revision was merged to the branch mainline in revision 1863.
  • Revision ID: mordred@inaugust.com-20101019215826-ofh15co6vp47vndb
Merge Monty - Fixed the valgrind errors, made it so that haildb works in trunk with no extra magic.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "drizzled/records.h"
30
30
#include "drizzled/internal/my_sys.h"
31
31
#include "drizzled/internal/iocache.h"
32
 
#include "drizzled/transaction_services.h"
33
 
#include "drizzled/filesort.h"
34
32
 
35
33
#include <boost/dynamic_bitset.hpp>
36
34
#include <list>
98
96
  /* Copy the newly read columns into the new record. */
99
97
  for (field_p= table->getFields(); (field= *field_p); field_p++)
100
98
  {
101
 
    if (unique_map.test(field->position()))
 
99
    if (unique_map.test(field->field_index))
102
100
    {
103
101
      field->copy_from_tmp(table->getShare()->rec_buff_length);
104
102
    }
129
127
 
130
128
int mysql_update(Session *session, TableList *table_list,
131
129
                 List<Item> &fields, List<Item> &values, COND *conds,
132
 
                 uint32_t order_num, Order *order,
 
130
                 uint32_t order_num, order_st *order,
133
131
                 ha_rows limit, enum enum_duplicates,
134
132
                 bool ignore)
135
133
{
136
134
  bool          using_limit= limit != HA_POS_ERROR;
137
135
  bool          used_key_is_modified;
138
136
  bool          transactional_table;
 
137
  bool          can_compare_record;
139
138
  int           error;
140
139
  uint          used_index= MAX_KEY, dup_key_found;
141
140
  bool          need_sort= true;
147
146
  Select_Lex    *select_lex= &session->lex->select_lex;
148
147
  uint64_t     id;
149
148
  List<Item> all_fields;
150
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
149
  Session::killed_state killed_status= Session::NOT_KILLED;
151
150
 
152
 
  DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
 
151
  DRIZZLE_UPDATE_START(session->query.c_str());
153
152
  if (session->openTablesLock(table_list))
154
153
  {
155
154
    DRIZZLE_UPDATE_DONE(1, 0, 0);
164
163
  table->quick_keys.reset();
165
164
 
166
165
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
167
 
  {
168
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
169
 
    return 1;
170
 
  }
 
166
    goto abort;
171
167
 
172
168
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
173
169
  /* Check the fields we are going to modify */
174
170
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
175
 
  {
176
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
177
 
    return 1;
178
 
  }
179
 
 
 
171
    goto abort;
180
172
  if (table->timestamp_field)
181
173
  {
182
174
    // Don't set timestamp column if this is modified
189
181
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
190
182
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
191
183
      {
192
 
        table->setWriteSet(table->timestamp_field->position());
 
184
        table->setWriteSet(table->timestamp_field->field_index);
193
185
      }
194
186
    }
195
187
  }
197
189
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
198
190
  {
199
191
    free_underlaid_joins(session, select_lex);
200
 
    DRIZZLE_UPDATE_DONE(1, 0, 0);
201
 
 
202
 
    return 1;
 
192
    goto abort;
203
193
  }
204
194
 
205
195
  if (select_lex->inner_refs_list.elements &&
247
237
    session->main_da.reset_diagnostics_area();
248
238
    free_underlaid_joins(session, select_lex);
249
239
    if (error)
250
 
    {
251
 
      DRIZZLE_UPDATE_DONE(1, 0, 0);
252
 
      return 1;
253
 
    }
 
240
      goto abort;                               // Error in where
254
241
    DRIZZLE_UPDATE_DONE(0, 0, 0);
255
242
    session->my_ok();                           // No matching records
256
243
    return 0;
313
300
      uint32_t         length= 0;
314
301
      SortField  *sortorder;
315
302
      ha_rows examined_rows;
316
 
      FileSort filesort(*session);
317
303
 
318
 
      table->sort.io_cache= new internal::IO_CACHE;
 
304
      table->sort.io_cache = new internal::IO_CACHE;
319
305
 
320
306
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
321
 
          (table->sort.found_records= filesort.run(table, sortorder, length,
322
 
                                                   select, limit, 1,
323
 
                                                   examined_rows)) == HA_POS_ERROR)
 
307
          (table->sort.found_records= filesort(session, table, sortorder, length,
 
308
                                               select, limit, 1,
 
309
                                               &examined_rows))
 
310
          == HA_POS_ERROR)
324
311
      {
325
312
        goto err;
326
313
      }
340
327
      */
341
328
 
342
329
      internal::IO_CACHE tempfile;
343
 
      if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
344
 
      {
 
330
      if (open_cached_file(&tempfile, drizzle_tmpdir.c_str(),TEMP_PREFIX,
 
331
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
345
332
        goto err;
346
 
      }
347
333
 
348
334
      /* If quick select is used, initialize it before retrieving rows. */
349
335
      if (select && select->quick && select->quick->reset())
373
359
      session->set_proc_info("Searching rows for update");
374
360
      ha_rows tmp_limit= limit;
375
361
 
376
 
      while (not(error= info.read_record(&info)) && not session->getKilled())
 
362
      while (!(error=info.read_record(&info)) && !session->killed)
377
363
      {
378
364
        if (!(select && select->skip_record()))
379
365
        {
396
382
        else
397
383
          table->cursor->unlock_row();
398
384
      }
399
 
      if (session->getKilled() && not error)
 
385
      if (session->killed && !error)
400
386
        error= 1;                               // Aborted
401
387
      limit= tmp_limit;
402
388
      table->cursor->try_semi_consistent_read(0);
416
402
        select= new optimizer::SqlSelect;
417
403
        select->head=table;
418
404
      }
419
 
      if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
 
405
      if (reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
420
406
        error=1;
421
407
      // Read row ptrs from this cursor
422
408
      memcpy(select->file, &tempfile, sizeof(tempfile));
458
444
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
459
445
    table->prepare_for_position();
460
446
 
461
 
  while (not (error=info.read_record(&info)) && not session->getKilled())
 
447
  /*
 
448
    We can use compare_record() to optimize away updates if
 
449
    the table handler is returning all columns OR if
 
450
    if all updated columns are read
 
451
  */
 
452
  can_compare_record= (! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
 
453
                       table->write_set->is_subset_of(*table->read_set));
 
454
 
 
455
  while (! (error=info.read_record(&info)) && !session->killed)
462
456
  {
463
 
    if (not (select && select->skip_record()))
 
457
    if (! (select && select->skip_record()))
464
458
    {
465
459
      if (table->cursor->was_semi_consistent_read())
466
460
        continue;  /* repeat the read of the same row if it still exists */
471
465
 
472
466
      found++;
473
467
 
474
 
      if (! table->records_are_comparable() || table->compare_records())
 
468
      if (!can_compare_record || table->compare_record())
475
469
      {
476
470
        /* Non-batched update */
477
471
        error= table->cursor->updateRecord(table->getUpdateRecord(),
480
474
        table->auto_increment_field_not_null= false;
481
475
 
482
476
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
483
 
        {
 
477
        {
484
478
          if (error != HA_ERR_RECORD_IS_THE_SAME)
485
479
            updated++;
486
480
          else
487
481
            error= 0;
488
 
        }
489
 
        else if (! ignore ||
 
482
        }
 
483
        else if (! ignore ||
490
484
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
491
 
        {
 
485
        {
492
486
          /*
493
487
            If (ignore && error is ignorable) we don't have to
494
488
            do anything; otherwise...
499
493
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
500
494
 
501
495
          prepare_record_for_error_message(error, table);
502
 
          table->print_error(error,MYF(flags));
503
 
          error= 1;
504
 
          break;
505
 
        }
 
496
          table->print_error(error,MYF(flags));
 
497
          error= 1;
 
498
          break;
 
499
        }
506
500
      }
507
501
 
508
502
      if (!--limit && using_limit)
524
518
    It's assumed that if an error was set in combination with an effective
525
519
    killed status then the error is due to killing.
526
520
  */
527
 
  killed_status= session->getKilled(); // get the status of the volatile
 
521
  killed_status= session->killed; // get the status of the volatile
528
522
  // simulated killing after the loop must be ineffective for binlogging
529
523
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
530
524
 
589
583
  }
590
584
  session->abort_on_warning= 0;
591
585
 
 
586
abort:
592
587
  DRIZZLE_UPDATE_DONE(1, 0, 0);
593
588
  return 1;
594
589
}
609
604
    true  error
610
605
*/
611
606
bool mysql_prepare_update(Session *session, TableList *table_list,
612
 
                         Item **conds, uint32_t order_num, Order *order)
 
607
                         Item **conds, uint32_t order_num, order_st *order)
613
608
{
614
609
  List<Item> all_fields;
615
610
  Select_Lex *select_lex= &session->lex->select_lex;
632
627
    TableList *duplicate;
633
628
    if ((duplicate= unique_table(table_list, table_list->next_global)))
634
629
    {
635
 
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
 
630
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
636
631
      return true;
637
632
    }
638
633
  }