~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2009-01-06 18:46:25 UTC
  • mto: This revision was merged to the branch mainline in revision 762.
  • Revision ID: mordred@inaugust.com-20090106184625-kqu7nsnwjwm5jv4s
Enabled dirty_close.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <drizzled/probes.h>
25
25
#include <drizzled/sql_base.h>
26
26
#include <drizzled/field/timestamp.h>
27
 
#include <drizzled/field/fstring.h>
28
27
 
29
28
/*
30
29
  check that all fields are real fields
82
81
  uint32_t keynr;
83
82
  MY_BITMAP unique_map; /* Fields in offended unique. */
84
83
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
85
 
  
 
84
 
86
85
  /*
87
86
    Only duplicate key errors print the key value.
88
87
    If storage engine does always read all columns, we have the value alraedy.
176
175
  uint64_t     id;
177
176
  List<Item> all_fields;
178
177
  Session::killed_state killed_status= Session::NOT_KILLED;
179
 
  
 
178
 
180
179
  for ( ; ; )
181
180
  {
182
181
    if (open_tables(session, &table_list, &table_count, 0))
293
292
  table->mark_columns_needed_for_update();
294
293
 
295
294
  /* Check if we are modifying a key that we are used to search with */
296
 
  
 
295
 
297
296
  if (select && select->quick)
298
297
  {
299
298
    used_index= select->quick->index;
338
337
      SORT_FIELD  *sortorder;
339
338
      ha_rows examined_rows;
340
339
 
341
 
      table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
342
 
                                                    MYF(MY_FAE | MY_ZEROFILL));
 
340
      table->sort.io_cache = new IO_CACHE;
 
341
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
 
342
 
343
343
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
344
344
          (table->sort.found_records= filesort(session, table, sortorder, length,
345
345
                                               select, limit, 1,
420
420
      limit= tmp_limit;
421
421
      table->file->try_semi_consistent_read(0);
422
422
      end_read_record(&info);
423
 
     
 
423
 
424
424
      /* Change select to use tempfile */
425
425
      if (select)
426
426
      {
447
447
 
448
448
  if (ignore)
449
449
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
450
 
  
 
450
 
451
451
  if (select && select->quick && select->quick->reset())
452
452
    goto err;
453
453
  table->file->try_semi_consistent_read(1);
454
454
  init_read_record(&info,session,table,select,0,1);
455
455
 
456
456
  updated= found= 0;
457
 
  /* Generate an error when trying to set a NOT NULL field to NULL. */
458
 
  session->count_cuted_fields= ignore ? CHECK_FIELD_WARN
459
 
                                  : CHECK_FIELD_ERROR_FOR_NULL;
460
 
  session->cuted_fields=0L;
 
457
  /*
 
458
   * Per the SQL standard, inserting NULL into a NOT NULL
 
459
   * field requires an error to be thrown.
 
460
   *
 
461
   * @NOTE
 
462
   *
 
463
   * NULL check and handling occurs in field_conv.cc
 
464
   */
 
465
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
466
  session->cuted_fields= 0L;
461
467
  session->set_proc_info("Updating");
462
468
 
463
469
  transactional_table= table->file->has_transactions();
506
512
 
507
513
            1) is covered by exec_bulk_update calls.
508
514
            2) and 3) is handled by the bulk_update_row method.
509
 
            
 
515
 
510
516
            bulk_update_row can execute the updates including the one
511
517
            defined in the bulk_update_row or not including the row
512
518
            in the call. This is up to the handler implementation and can
664
670
  */
665
671
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
666
672
  {
667
 
    if (drizzle_bin_log.is_open())
668
 
    {
669
 
      if (error < 0)
670
 
        session->clear_error();
671
 
      if (session->binlog_query(Session::ROW_QUERY_TYPE,
672
 
                            session->query, session->query_length,
673
 
                            transactional_table, false, killed_status) &&
674
 
          transactional_table)
675
 
      {
676
 
        error=1;                                // Rollback update
677
 
      }
678
 
    }
679
673
    if (session->transaction.stmt.modified_non_trans_table)
680
674
      session->transaction.all.modified_non_trans_table= true;
681
675
  }
738
732
 
739
733
  session->lex->allow_sum_func= 0;
740
734
 
741
 
  if (setup_tables_and_check_access(session, &select_lex->context, 
 
735
  if (setup_tables_and_check_access(session, &select_lex->context,
742
736
                                    &select_lex->top_join_list,
743
737
                                    table_list,
744
738
                                    &select_lex->leaf_tables,
765
759
 
766
760
 
767
761
/***************************************************************************
768
 
  Update multiple tables from join 
 
762
  Update multiple tables from join
769
763
***************************************************************************/
770
764
 
771
765
/*
778
772
  Item_field *item;
779
773
  table_map map= 0;
780
774
 
781
 
  while ((item= (Item_field *) item_it++)) 
 
775
  while ((item= (Item_field *) item_it++))
782
776
    map|= item->used_tables();
783
777
  return map;
784
778
}
813
807
  const bool using_lock_tables= session->locked_tables != 0;
814
808
  bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
815
809
  bool need_reopen= false;
816
 
  
 
810
 
817
811
 
818
812
  /* following need for prepared statements, to run next time multi-update */
819
813
  session->lex->sql_command= SQLCOM_UPDATE_MULTI;
933
927
    further check in multi_update::prepare whether to use record cache.
934
928
  */
935
929
  lex->select_lex.exclude_from_table_unique_test= false;
936
 
 
 
930
 
937
931
  if (session->fill_derived_tables() &&
938
932
      mysql_handle_derived(lex, &mysql_derived_filling))
939
933
    return(true);
957
951
{
958
952
  multi_update *result;
959
953
  bool res;
960
 
  
 
954
 
961
955
  if (!(result= new multi_update(table_list,
962
956
                                 session->lex->select_lex.leaf_tables,
963
957
                                 fields, values,
1016
1010
  List_iterator_fast<Item> value_it(*values);
1017
1011
  uint32_t i, max_fields;
1018
1012
  uint32_t leaf_table_count= 0;
1019
 
  
 
1013
 
1020
1014
  session->count_cuted_fields= CHECK_FIELD_WARN;
1021
1015
  session->cuted_fields=0L;
1022
1016
  session->set_proc_info("updating main table");
1182
1176
multi_update::initialize_tables(JOIN *join)
1183
1177
{
1184
1178
  TableList *table_ref;
1185
 
  
 
1179
 
1186
1180
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
1187
1181
    return(1);
1188
1182
  main_table=join->join_tab->table;
1227
1221
    Table *tbl= table;
1228
1222
    do
1229
1223
    {
1230
 
      Field_string *field= new Field_string(tbl->file->ref_length, 0,
1231
 
                                            tbl->alias, &my_charset_bin);
1232
 
#ifdef OLD
1233
1224
      Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1234
1225
                                                  tbl->alias, tbl->s, &my_charset_bin);
1235
 
#endif
1236
1226
      if (!field)
1237
1227
        return(1);
1238
1228
      field->init(tbl);
1411
1401
      do
1412
1402
      {
1413
1403
        tbl->file->position(tbl->record[0]);
1414
 
        memcpy(tmp_table->field[field_num]->ptr,
1415
 
               tbl->file->ref, tbl->file->ref_length);
 
1404
        Field_varstring *ref_field=
 
1405
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
 
1406
        ref_field->store((char *)tbl->file->ref, tbl->file->ref_length,
 
1407
                         &my_charset_bin);
1416
1408
        field_num++;
1417
1409
      } while ((tbl= tbl_it++));
1418
1410
 
1466
1458
    if (do_update && table_count > 1)
1467
1459
    {
1468
1460
      /* Add warning here */
1469
 
      /* 
 
1461
      /*
1470
1462
         todo/fixme: do_update() is never called with the arg 1.
1471
1463
         should it change the signature to become argless?
1472
1464
      */
1475
1467
  }
1476
1468
  if (session->transaction.stmt.modified_non_trans_table)
1477
1469
  {
1478
 
    /*
1479
 
      The query has to binlog because there's a modified non-transactional table
1480
 
      either from the query's list or via a stored routine: bug#13270,23333
1481
 
    */
1482
 
    if (drizzle_bin_log.is_open())
1483
 
    {
1484
 
      /*
1485
 
        Session::killed status might not have been set ON at time of an error
1486
 
        got caught and if happens later the killed error is written
1487
 
        into repl event.
1488
 
      */
1489
 
      session->binlog_query(Session::ROW_QUERY_TYPE,
1490
 
                        session->query, session->query_length,
1491
 
                        transactional_tables, false);
1492
 
    }
1493
1470
    session->transaction.all.modified_non_trans_table= true;
1494
1471
  }
1495
1472
  assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1503
1480
  ha_rows org_updated;
1504
1481
  Table *table, *tmp_table;
1505
1482
  List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
1506
 
  
 
1483
 
1507
1484
  do_update= 0;                                 // Don't retry this function
1508
1485
  if (!found)
1509
1486
    return(0);
1533
1510
      Setup copy functions to copy fields from temporary table
1534
1511
    */
1535
1512
    List_iterator_fast<Item> field_it(*fields_for_table[offset]);
1536
 
    Field **field= tmp_table->field + 
 
1513
    Field **field= tmp_table->field +
1537
1514
                   1 + unupdated_check_opt_tables.elements; // Skip row pointers
1538
1515
    Copy_field *copy_field_ptr= copy_field, *copy_field_end;
1539
1516
    for ( ; *field ; field++)
1570
1547
      uint32_t field_num= 0;
1571
1548
      do
1572
1549
      {
 
1550
        Field_varstring *ref_field=
 
1551
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1573
1552
        if((local_error=
1574
1553
              tbl->file->rnd_pos(tbl->record[0],
1575
 
                                (unsigned char *) tmp_table->field[field_num]->ptr)))
 
1554
                                (unsigned char *) ref_field->ptr
 
1555
                                 + ref_field->length_bytes)))
1576
1556
          goto err;
1577
1557
        field_num++;
1578
1558
      } while((tbl= check_opt_it++));
1655
1635
  char buff[STRING_BUFFER_USUAL_SIZE];
1656
1636
  uint64_t id;
1657
1637
  Session::killed_state killed_status= Session::NOT_KILLED;
1658
 
  
 
1638
 
1659
1639
  session->set_proc_info("updating reference tables");
1660
1640
 
1661
 
  /* 
 
1641
  /*
1662
1642
     Does updates for the last n - 1 tables, returns 0 if ok;
1663
1643
     error takes into account killed status gained in do_updates()
1664
1644
  */
1674
1654
    Write the SQL statement to the binlog if we updated
1675
1655
    rows and we succeeded or if we updated some non
1676
1656
    transactional tables.
1677
 
    
 
1657
 
1678
1658
    The query has to binlog because there's a modified non-transactional table
1679
1659
    either from the query's list or via a stored routine: bug#13270,23333
1680
1660
  */
1681
1661
 
1682
 
  assert(trans_safe || !updated || 
 
1662
  assert(trans_safe || !updated ||
1683
1663
              session->transaction.stmt.modified_non_trans_table);
1684
1664
  if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1685
1665
  {
1686
 
    if (drizzle_bin_log.is_open())
1687
 
    {
1688
 
      if (local_error == 0)
1689
 
        session->clear_error();
1690
 
      if (session->binlog_query(Session::ROW_QUERY_TYPE,
1691
 
                            session->query, session->query_length,
1692
 
                            transactional_tables, false, killed_status) &&
1693
 
          trans_safe)
1694
 
      {
1695
 
        local_error= 1;                         // Rollback update
1696
 
      }
1697
 
    }
1698
1666
    if (session->transaction.stmt.modified_non_trans_table)
1699
1667
      session->transaction.all.modified_non_trans_table= true;
1700
1668
  }