~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Brian Aker
  • Date: 2010-10-27 21:00:49 UTC
  • mto: This revision was merged to the branch mainline in revision 1886.
  • Revision ID: brian@tangent.org-20101027210049-zfpgx2cfbrh8maq9
A couple of fixes to documentation.

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"
31
30
#include "drizzled/internal/my_sys.h"
32
31
#include "drizzled/internal/iocache.h"
33
 
#include "drizzled/transaction_services.h"
34
 
#include "drizzled/filesort.h"
35
 
#include "drizzled/plugin/storage_engine.h"
36
32
 
37
33
#include <boost/dynamic_bitset.hpp>
38
34
#include <list>
100
96
  /* Copy the newly read columns into the new record. */
101
97
  for (field_p= table->getFields(); (field= *field_p); field_p++)
102
98
  {
103
 
    if (unique_map.test(field->position()))
 
99
    if (unique_map.test(field->field_index))
104
100
    {
105
101
      field->copy_from_tmp(table->getShare()->rec_buff_length);
106
102
    }
114
110
  Process usual UPDATE
115
111
 
116
112
  SYNOPSIS
117
 
    update_query()
 
113
    mysql_update()
118
114
    session                     thread handler
119
115
    fields              fields for update
120
116
    values              values of fields for update
129
125
    1  - error
130
126
*/
131
127
 
132
 
int update_query(Session *session, TableList *table_list,
 
128
int mysql_update(Session *session, TableList *table_list,
133
129
                 List<Item> &fields, List<Item> &values, COND *conds,
134
 
                 uint32_t order_num, Order *order,
 
130
                 uint32_t order_num, order_st *order,
135
131
                 ha_rows limit, enum enum_duplicates,
136
132
                 bool ignore)
137
133
{
138
134
  bool          using_limit= limit != HA_POS_ERROR;
139
135
  bool          used_key_is_modified;
140
136
  bool          transactional_table;
141
 
  int           error= 0;
 
137
  bool          can_compare_record;
 
138
  int           error;
142
139
  uint          used_index= MAX_KEY, dup_key_found;
143
140
  bool          need_sort= true;
144
141
  ha_rows       updated, found;
149
146
  Select_Lex    *select_lex= &session->lex->select_lex;
150
147
  uint64_t     id;
151
148
  List<Item> all_fields;
152
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
149
  Session::killed_state killed_status= Session::NOT_KILLED;
153
150
 
154
 
  DRIZZLE_UPDATE_START(session->getQueryString()->c_str());
 
151
  DRIZZLE_UPDATE_START(session->query.c_str());
155
152
  if (session->openTablesLock(table_list))
156
153
  {
157
154
    DRIZZLE_UPDATE_DONE(1, 0, 0);
165
162
  table->covering_keys= table->getShare()->keys_in_use;
166
163
  table->quick_keys.reset();
167
164
 
168
 
  if (prepare_update(session, table_list, &conds, order_num, order))
 
165
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
169
166
  {
170
167
    DRIZZLE_UPDATE_DONE(1, 0, 0);
171
168
    return 1;
191
188
      if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
192
189
          table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
193
190
      {
194
 
        table->setWriteSet(table->timestamp_field->position());
 
191
        table->setWriteSet(table->timestamp_field->field_index);
195
192
      }
196
193
    }
197
194
  }
208
205
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
209
206
  {
210
207
    DRIZZLE_UPDATE_DONE(1, 0, 0);
211
 
    return 1;
 
208
    return -1;
212
209
  }
213
210
 
214
211
  if (conds)
248
245
     */
249
246
    session->main_da.reset_diagnostics_area();
250
247
    free_underlaid_joins(session, select_lex);
251
 
    if (error || session->is_error())
 
248
    if (error)
252
249
    {
253
250
      DRIZZLE_UPDATE_DONE(1, 0, 0);
254
251
      return 1;
315
312
      uint32_t         length= 0;
316
313
      SortField  *sortorder;
317
314
      ha_rows examined_rows;
318
 
      FileSort filesort(*session);
319
315
 
320
 
      table->sort.io_cache= new internal::IO_CACHE;
 
316
      table->sort.io_cache = new internal::IO_CACHE;
321
317
 
322
318
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
323
 
          (table->sort.found_records= filesort.run(table, sortorder, length,
324
 
                                                   select, limit, 1,
325
 
                                                   examined_rows)) == HA_POS_ERROR)
 
319
          (table->sort.found_records= filesort(session, table, sortorder, length,
 
320
                                               select, limit, 1,
 
321
                                               &examined_rows))
 
322
          == HA_POS_ERROR)
326
323
      {
327
324
        goto err;
328
325
      }
342
339
      */
343
340
 
344
341
      internal::IO_CACHE tempfile;
345
 
      if (tempfile.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
346
 
      {
 
342
      if (open_cached_file(&tempfile, drizzle_tmpdir.c_str(),TEMP_PREFIX,
 
343
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
347
344
        goto err;
348
 
      }
349
345
 
350
346
      /* If quick select is used, initialize it before retrieving rows. */
351
347
      if (select && select->quick && select->quick->reset())
365
361
 
366
362
      if (used_index == MAX_KEY || (select && select->quick))
367
363
      {
368
 
        if ((error= info.init_read_record(session, table, select, 0, true)))
369
 
          goto err;
 
364
        info.init_read_record(session, table, select, 0, true);
370
365
      }
371
366
      else
372
367
      {
373
 
        if ((error= info.init_read_record_idx(session, table, 1, used_index)))
374
 
          goto err;
 
368
        info.init_read_record_idx(session, table, 1, used_index);
375
369
      }
376
370
 
377
371
      session->set_proc_info("Searching rows for update");
378
372
      ha_rows tmp_limit= limit;
379
373
 
380
 
      while (not(error= info.read_record(&info)) && not session->getKilled())
 
374
      while (!(error=info.read_record(&info)) && !session->killed)
381
375
      {
382
376
        if (!(select && select->skip_record()))
383
377
        {
400
394
        else
401
395
          table->cursor->unlock_row();
402
396
      }
403
 
      if (session->getKilled() && not error)
 
397
      if (session->killed && !error)
404
398
        error= 1;                               // Aborted
405
399
      limit= tmp_limit;
406
400
      table->cursor->try_semi_consistent_read(0);
417
411
      }
418
412
      else
419
413
      {
420
 
        select= new optimizer::SqlSelect();
 
414
        select= new optimizer::SqlSelect;
421
415
        select->head=table;
422
416
      }
423
 
      if (tempfile.reinit_io_cache(internal::READ_CACHE,0L,0,0))
 
417
      if (reinit_io_cache(&tempfile,internal::READ_CACHE,0L,0,0))
424
418
        error=1;
425
419
      // Read row ptrs from this cursor
426
420
      memcpy(select->file, &tempfile, sizeof(tempfile));
437
431
  if (select && select->quick && select->quick->reset())
438
432
    goto err;
439
433
  table->cursor->try_semi_consistent_read(1);
440
 
  if ((error= info.init_read_record(session, table, select, 0, true)))
441
 
  {
442
 
    goto err;
443
 
  }
 
434
  info.init_read_record(session, table, select, 0, true);
444
435
 
445
436
  updated= found= 0;
446
437
  /*
456
447
  session->set_proc_info("Updating");
457
448
 
458
449
  transactional_table= table->cursor->has_transactions();
459
 
  session->setAbortOnWarning(test(!ignore));
 
450
  session->abort_on_warning= test(!ignore);
460
451
 
461
452
  /*
462
453
    Assure that we can use position()
465
456
  if (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ))
466
457
    table->prepare_for_position();
467
458
 
468
 
  while (not (error=info.read_record(&info)) && not session->getKilled())
 
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
  */
 
464
  can_compare_record= (! (table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ)) ||
 
465
                       table->write_set->is_subset_of(*table->read_set));
 
466
 
 
467
  while (! (error=info.read_record(&info)) && !session->killed)
469
468
  {
470
 
    if (not (select && select->skip_record()))
 
469
    if (! (select && select->skip_record()))
471
470
    {
472
471
      if (table->cursor->was_semi_consistent_read())
473
472
        continue;  /* repeat the read of the same row if it still exists */
478
477
 
479
478
      found++;
480
479
 
481
 
      if (! table->records_are_comparable() || table->compare_records())
 
480
      if (!can_compare_record || table->compare_record())
482
481
      {
483
482
        /* Non-batched update */
484
483
        error= table->cursor->updateRecord(table->getUpdateRecord(),
487
486
        table->auto_increment_field_not_null= false;
488
487
 
489
488
        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
490
 
        {
 
489
        {
491
490
          if (error != HA_ERR_RECORD_IS_THE_SAME)
492
491
            updated++;
493
492
          else
494
493
            error= 0;
495
 
        }
496
 
        else if (! ignore ||
 
494
        }
 
495
        else if (! ignore ||
497
496
                 table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
498
 
        {
 
497
        {
499
498
          /*
500
499
            If (ignore && error is ignorable) we don't have to
501
500
            do anything; otherwise...
506
505
            flags|= ME_FATALERROR; /* Other handler errors are fatal */
507
506
 
508
507
          prepare_record_for_error_message(error, table);
509
 
          table->print_error(error,MYF(flags));
510
 
          error= 1;
511
 
          break;
512
 
        }
 
508
          table->print_error(error,MYF(flags));
 
509
          error= 1;
 
510
          break;
 
511
        }
513
512
      }
514
513
 
515
514
      if (!--limit && using_limit)
531
530
    It's assumed that if an error was set in combination with an effective
532
531
    killed status then the error is due to killing.
533
532
  */
534
 
  killed_status= session->getKilled(); // get the status of the volatile
 
533
  killed_status= session->killed; // get the status of the volatile
535
534
  // simulated killing after the loop must be ineffective for binlogging
536
535
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
537
536
 
578
577
     * lp bug# 439719
579
578
     */
580
579
    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();
 
580
    session->my_ok((ulong) session->row_count_func, found, id, buff);
 
581
    session->status_var.updated_row_count+= session->row_count_func;
583
582
  }
584
583
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;              /* calc cuted fields */
585
 
  session->setAbortOnWarning(false);
 
584
  session->abort_on_warning= 0;
586
585
  DRIZZLE_UPDATE_DONE((error >= 0 || session->is_error()), found, updated);
587
586
  return ((error >= 0 || session->is_error()) ? 1 : 0);
588
587
 
589
588
err:
590
 
  if (error != 0)
591
 
    table->print_error(error,MYF(0));
592
 
 
593
589
  delete select;
594
590
  free_underlaid_joins(session, select_lex);
595
591
  if (table->key_read)
597
593
    table->key_read=0;
598
594
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
599
595
  }
600
 
  session->setAbortOnWarning(false);
 
596
  session->abort_on_warning= 0;
601
597
 
602
598
  DRIZZLE_UPDATE_DONE(1, 0, 0);
603
599
  return 1;
607
603
  Prepare items in UPDATE statement
608
604
 
609
605
  SYNOPSIS
610
 
    prepare_update()
 
606
    mysql_prepare_update()
611
607
    session                     - thread handler
612
608
    table_list          - global/local table list
613
609
    conds               - conditions
618
614
    false OK
619
615
    true  error
620
616
*/
621
 
bool prepare_update(Session *session, TableList *table_list,
622
 
                         Item **conds, uint32_t order_num, Order *order)
 
617
bool mysql_prepare_update(Session *session, TableList *table_list,
 
618
                         Item **conds, uint32_t order_num, order_st *order)
623
619
{
624
620
  List<Item> all_fields;
625
621
  Select_Lex *select_lex= &session->lex->select_lex;