~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

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