~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Patrick Crews
  • Date: 2010-12-07 20:02:50 UTC
  • Revision ID: gleebix@gmail.com-20101207200250-6a27jgqalgw5bsb5
Added disabled.def file to disable drizzleslap due to Bug#684269.  Need to skip for tarball release this round

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/*
18
18
  Single table and multi table updates of tables.
 
19
  Multi-table updates were introduced by Sinisa & Monty
19
20
*/
20
 
 
21
21
#include "config.h"
22
 
 
23
22
#include "drizzled/sql_select.h"
24
23
#include "drizzled/error.h"
25
24
#include "drizzled/probes.h"
26
25
#include "drizzled/sql_base.h"
27
 
#include "drizzled/field/epoch.h"
 
26
#include "drizzled/field/timestamp.h"
28
27
#include "drizzled/sql_parse.h"
29
28
#include "drizzled/optimizer/range.h"
30
29
#include "drizzled/records.h"
32
31
#include "drizzled/internal/iocache.h"
33
32
#include "drizzled/transaction_services.h"
34
33
#include "drizzled/filesort.h"
35
 
#include "drizzled/plugin/storage_engine.h"
36
34
 
37
35
#include <boost/dynamic_bitset.hpp>
38
36
#include <list>
100
98
  /* Copy the newly read columns into the new record. */
101
99
  for (field_p= table->getFields(); (field= *field_p); field_p++)
102
100
  {
103
 
    if (unique_map.test(field->position()))
 
101
    if (unique_map.test(field->field_index))
104
102
    {
105
103
      field->copy_from_tmp(table->getShare()->rec_buff_length);
106
104
    }
114
112
  Process usual UPDATE
115
113
 
116
114
  SYNOPSIS
117
 
    update_query()
 
115
    mysql_update()
118
116
    session                     thread handler
119
117
    fields              fields for update
120
118
    values              values of fields for update
129
127
    1  - error
130
128
*/
131
129
 
132
 
int update_query(Session *session, TableList *table_list,
 
130
int mysql_update(Session *session, TableList *table_list,
133
131
                 List<Item> &fields, List<Item> &values, COND *conds,
134
132
                 uint32_t order_num, Order *order,
135
133
                 ha_rows limit, enum enum_duplicates,
138
136
  bool          using_limit= limit != HA_POS_ERROR;
139
137
  bool          used_key_is_modified;
140
138
  bool          transactional_table;
141
 
  int           error= 0;
 
139
  bool          can_compare_record;
 
140
  int           error;
142
141
  uint          used_index= MAX_KEY, dup_key_found;
143
142
  bool          need_sort= true;
144
143
  ha_rows       updated, found;
165
164
  table->covering_keys= table->getShare()->keys_in_use;
166
165
  table->quick_keys.reset();
167
166
 
168
 
  if (prepare_update(session, table_list, &conds, order_num, order))
 
167
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
169
168
  {
170
169
    DRIZZLE_UPDATE_DONE(1, 0, 0);
171
170
    return 1;
191
190
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
192
191
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
193
192
      {
194
 
        table->setWriteSet(table->timestamp_field->position());
 
193
        table->setWriteSet(table->timestamp_field->field_index);
195
194
      }
196
195
    }
197
196
  }
208
207
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
209
208
  {
210
209
    DRIZZLE_UPDATE_DONE(1, 0, 0);
211
 
    return 1;
 
210
    return -1;
212
211
  }
213
212
 
214
213
  if (conds)
248
247
     */
249
248
    session->main_da.reset_diagnostics_area();
250
249
    free_underlaid_joins(session, select_lex);
251
 
    if (error || session->is_error())
 
250
    if (error)
252
251
    {
253
252
      DRIZZLE_UPDATE_DONE(1, 0, 0);
254
253
      return 1;
365
364
 
366
365
      if (used_index == MAX_KEY || (select && select->quick))
367
366
      {
368
 
        if ((error= info.init_read_record(session, table, select, 0, true)))
369
 
          goto err;
 
367
        info.init_read_record(session, table, select, 0, true);
370
368
      }
371
369
      else
372
370
      {
373
 
        if ((error= info.init_read_record_idx(session, table, 1, used_index)))
374
 
          goto err;
 
371
        info.init_read_record_idx(session, table, 1, used_index);
375
372
      }
376
373
 
377
374
      session->set_proc_info("Searching rows for update");
417
414
      }
418
415
      else
419
416
      {
420
 
        select= new optimizer::SqlSelect();
 
417
        select= new optimizer::SqlSelect;
421
418
        select->head=table;
422
419
      }
423
420
      if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
437
434
  if (select && select->quick && select->quick->reset())
438
435
    goto err;
439
436
  table->cursor->try_semi_consistent_read(1);
440
 
  if ((error= info.init_read_record(session, table, select, 0, true)))
441
 
  {
442
 
    goto err;
443
 
  }
 
437
  info.init_read_record(session, table, select, 0, true);
444
438
 
445
439
  updated= found= 0;
446
440
  /*
456
450
  session->set_proc_info("Updating");
457
451
 
458
452
  transactional_table= table->cursor->has_transactions();
459
 
  session->setAbortOnWarning(test(!ignore));
 
453
  session->abort_on_warning= test(!ignore);
460
454
 
461
455
  /*
462
456
    Assure that we can use position()
465
459
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
466
460
    table->prepare_for_position();
467
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
  */
 
467
  can_compare_record= (! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
 
468
                       table->write_set->is_subset_of(*table->read_set));
 
469
 
468
470
  while (not (error=info.read_record(&info)) && not session->getKilled())
469
471
  {
470
472
    if (not (select && select->skip_record()))
474
476
 
475
477
      table->storeRecord();
476
478
      if (fill_record(session, fields, values))
 
479
      {
 
480
        /*
 
481
         * If we updated some rows before this one failed (updated > 0),
 
482
         * then we will need to undo adding those records to the
 
483
         * replication Statement message.
 
484
         */
 
485
        if (updated > 0)
 
486
        {
 
487
          TransactionServices &ts= TransactionServices::singleton();
 
488
          ts.removeStatementRecords(session, updated);
 
489
        }
 
490
 
477
491
        break;
 
492
      }
478
493
 
479
494
      found++;
480
495
 
481
 
      if (! table->records_are_comparable() || table->compare_records())
 
496
      if (!can_compare_record || table->compare_record())
482
497
      {
483
498
        /* Non-batched update */
484
499
        error= table->cursor->updateRecord(table->getUpdateRecord(),
578
593
     * lp bug# 439719
579
594
     */
580
595
    session->main_da.reset_diagnostics_area();
581
 
    session->my_ok((ulong) session->rowCount(), found, id, buff);
582
 
    session->status_var.updated_row_count+= session->rowCount();
 
596
    session->my_ok((ulong) session->row_count_func, found, id, buff);
 
597
    session->status_var.updated_row_count+= session->row_count_func;
583
598
  }
584
599
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;              /* calc cuted fields */
585
 
  session->setAbortOnWarning(false);
 
600
  session->abort_on_warning= 0;
586
601
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
587
602
  return ((error >= 0 || session->is_error()) ? 1 : 0);
588
603
 
589
604
err:
590
 
  if (error != 0)
591
 
    table->print_error(error,MYF(0));
592
 
 
593
605
  delete select;
594
606
  free_underlaid_joins(session, select_lex);
595
607
  if (table->key_read)
597
609
    table->key_read=0;
598
610
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
599
611
  }
600
 
  session->setAbortOnWarning(false);
 
612
  session->abort_on_warning= 0;
601
613
 
602
614
  DRIZZLE_UPDATE_DONE(1, 0, 0);
603
615
  return 1;
607
619
  Prepare items in UPDATE statement
608
620
 
609
621
  SYNOPSIS
610
 
    prepare_update()
 
622
    mysql_prepare_update()
611
623
    session                     - thread handler
612
624
    table_list          - global/local table list
613
625
    conds               - conditions
618
630
    false OK
619
631
    true  error
620
632
*/
621
 
bool prepare_update(Session *session, TableList *table_list,
 
633
bool mysql_prepare_update(Session *session, TableList *table_list,
622
634
                         Item **conds, uint32_t order_num, Order *order)
623
635
{
624
636
  List<Item> all_fields;