~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_update.cc

Removed DBUG symbols and fixed TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
  Single table and multi table updates of tables.
19
19
  Multi-table updates were introduced by Sinisa & Monty
20
20
*/
21
 
#include <drizzled/server_includes.h>
22
 
#include <drizzled/sql_select.h>
23
 
#include <drizzled/drizzled_error_messages.h>
 
21
 
 
22
#include "mysql_priv.h"
 
23
#include "sql_select.h"
 
24
 
 
25
/* Return 0 if row hasn't changed */
 
26
 
 
27
bool compare_record(TABLE *table)
 
28
{
 
29
  if (table->s->blob_fields + table->s->varchar_fields == 0)
 
30
    return cmp_record(table,record[1]);
 
31
  /* Compare null bits */
 
32
  if (memcmp(table->null_flags,
 
33
             table->null_flags+table->s->rec_buff_length,
 
34
             table->s->null_bytes))
 
35
    return true;                                // Diff in NULL value
 
36
  /* Compare updated fields */
 
37
  for (Field **ptr= table->field ; *ptr ; ptr++)
 
38
  {
 
39
    if (bitmap_is_set(table->write_set, (*ptr)->field_index) &&
 
40
        (*ptr)->cmp_binary_offset(table->s->rec_buff_length))
 
41
      return true;
 
42
  }
 
43
  return false;
 
44
}
 
45
 
24
46
 
25
47
/*
26
48
  check that all fields are real fields
71
93
  @param[in] table   table
72
94
*/
73
95
 
74
 
static void prepare_record_for_error_message(int error, Table *table)
 
96
static void prepare_record_for_error_message(int error, TABLE *table)
75
97
{
76
98
  Field **field_p;
77
99
  Field *field;
78
 
  uint32_t keynr;
 
100
  uint keynr;
79
101
  MY_BITMAP unique_map; /* Fields in offended unique. */
80
102
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
81
103
  
136
158
    fields              fields for update
137
159
    values              values of fields for update
138
160
    conds               WHERE clause expression
139
 
    order_num           number of elemen in order_st BY clause
140
 
    order               order_st BY clause list
 
161
    order_num           number of elemen in ORDER BY clause
 
162
    order               ORDER BY clause list
141
163
    limit               limit clause
142
164
    handle_duplicates   how to handle duplicates
143
165
 
149
171
*/
150
172
 
151
173
int mysql_update(THD *thd,
152
 
                 TableList *table_list,
 
174
                 TABLE_LIST *table_list,
153
175
                 List<Item> &fields,
154
 
                 List<Item> &values,
 
176
                 List<Item> &values,
155
177
                 COND *conds,
156
 
                 uint32_t order_num, order_st *order,
157
 
                 ha_rows limit,
158
 
                 enum enum_duplicates handle_duplicates __attribute__((unused)),
159
 
                 bool ignore)
 
178
                 uint order_num, ORDER *order,
 
179
                 ha_rows limit,
 
180
                 enum enum_duplicates handle_duplicates, bool ignore)
160
181
{
161
182
  bool          using_limit= limit != HA_POS_ERROR;
162
183
  bool          safe_update= test(thd->options & OPTION_SAFE_UPDATES);
165
186
  int           error, loc_error;
166
187
  uint          used_index= MAX_KEY, dup_key_found;
167
188
  bool          need_sort= true;
168
 
  uint32_t          table_count= 0;
 
189
  uint          table_count= 0;
169
190
  ha_rows       updated, found;
170
191
  key_map       old_covering_keys;
171
 
  Table         *table;
 
192
  TABLE         *table;
172
193
  SQL_SELECT    *select;
173
194
  READ_RECORD   info;
174
195
  SELECT_LEX    *select_lex= &thd->lex->select_lex;
175
196
  bool          need_reopen;
176
 
  uint64_t     id;
 
197
  ulonglong     id;
177
198
  List<Item> all_fields;
178
199
  THD::killed_state killed_status= THD::NOT_KILLED;
179
200
  
194
215
       mysql_handle_derived(thd->lex, &mysql_derived_filling)))
195
216
    return(1);
196
217
 
197
 
  DRIZZLE_UPDATE_START();
198
 
  thd->set_proc_info("init");
 
218
  MYSQL_UPDATE_START();
 
219
  thd_proc_info(thd, "init");
199
220
  table= table_list->table;
200
221
 
201
222
  /* Calculate "table->covering_keys" based on the WHERE */
233
254
  if (select_lex->inner_refs_list.elements &&
234
255
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
235
256
  {
236
 
    DRIZZLE_UPDATE_END();
 
257
    MYSQL_UPDATE_END();
237
258
    return(-1);
238
259
  }
239
260
 
269
290
    free_underlaid_joins(thd, select_lex);
270
291
    if (error)
271
292
      goto abort;                               // Error in where
272
 
    DRIZZLE_UPDATE_END();
 
293
    MYSQL_UPDATE_END();
273
294
    my_ok(thd);                         // No matching records
274
295
    return(0);
275
296
  }
330
351
    if (order && (need_sort || used_key_is_modified))
331
352
    {
332
353
      /*
333
 
        Doing an order_st BY;  Let filesort find and sort the rows we are going
 
354
        Doing an ORDER BY;  Let filesort find and sort the rows we are going
334
355
        to update
335
356
        NOTE: filesort will call table->prepare_for_position()
336
357
      */
337
 
      uint32_t         length= 0;
 
358
      uint         length= 0;
338
359
      SORT_FIELD  *sortorder;
339
360
      ha_rows examined_rows;
340
361
 
389
410
      else
390
411
        init_read_record_idx(&info, thd, table, 1, used_index);
391
412
 
392
 
      thd->set_proc_info("Searching rows for update");
 
413
      thd_proc_info(thd, "Searching rows for update");
393
414
      ha_rows tmp_limit= limit;
394
415
 
395
416
      while (!(error=info.read_record(&info)) && !thd->killed)
458
479
  thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
459
480
                                  : CHECK_FIELD_ERROR_FOR_NULL;
460
481
  thd->cuted_fields=0L;
461
 
  thd->set_proc_info("Updating");
 
482
  thd_proc_info(thd, "Updating");
462
483
 
463
484
  transactional_table= table->file->has_transactions();
464
 
  thd->abort_on_warning= test(!ignore);
 
485
  thd->abort_on_warning= test(!ignore &&
 
486
                              (thd->variables.sql_mode &
 
487
                               (MODE_STRICT_TRANS_TABLES |
 
488
                                MODE_STRICT_ALL_TABLES)));
465
489
  will_batch= !table->file->start_bulk_update();
466
490
 
467
491
  /*
493
517
 
494
518
      found++;
495
519
 
496
 
      if (!can_compare_record || table->compare_record())
 
520
      if (!can_compare_record || compare_record(table))
497
521
      {
498
522
        if (will_batch)
499
523
        {
650
674
 
651
675
  end_read_record(&info);
652
676
  delete select;
653
 
  thd->set_proc_info("end");
654
 
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
677
  thd_proc_info(thd, "end");
 
678
  VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
655
679
 
656
680
  /*
657
681
    error < 0 means really no error at all: we processed all rows until the
686
710
  id= thd->arg_of_last_insert_id_function ?
687
711
    thd->first_successful_insert_id_in_prev_stmt : 0;
688
712
 
689
 
  DRIZZLE_UPDATE_END();
 
713
  MYSQL_UPDATE_END();
690
714
  if (error < 0)
691
715
  {
692
716
    char buff[STRING_BUFFER_USUAL_SIZE];
711
735
  thd->abort_on_warning= 0;
712
736
 
713
737
abort:
714
 
  DRIZZLE_UPDATE_END();
 
738
  MYSQL_UPDATE_END();
715
739
  return(1);
716
740
}
717
741
 
723
747
    thd                 - thread handler
724
748
    table_list          - global/local table list
725
749
    conds               - conditions
726
 
    order_num           - number of order_st BY list entries
727
 
    order               - order_st BY clause list
 
750
    order_num           - number of ORDER BY list entries
 
751
    order               - ORDER BY clause list
728
752
 
729
753
  RETURN VALUE
730
754
    false OK
731
755
    true  error
732
756
*/
733
 
bool mysql_prepare_update(THD *thd, TableList *table_list,
734
 
                         Item **conds, uint32_t order_num, order_st *order)
 
757
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
 
758
                         Item **conds, uint order_num, ORDER *order)
735
759
{
 
760
  Item *fake_conds= 0;
736
761
  List<Item> all_fields;
737
762
  SELECT_LEX *select_lex= &thd->lex->select_lex;
738
763
  
740
765
    Statement-based replication of UPDATE ... LIMIT is not safe as order of
741
766
    rows is not defined, so in mixed mode we go to row-based.
742
767
 
743
 
    Note that we may consider a statement as safe if order_st BY primary_key
 
768
    Note that we may consider a statement as safe if ORDER BY primary_key
744
769
    is present. However it may confuse users to see very similiar statements
745
770
    replicated differently.
746
771
  */
765
790
 
766
791
  /* Check that we are not using table that we are updating in a sub select */
767
792
  {
768
 
    TableList *duplicate;
 
793
    TABLE_LIST *duplicate;
769
794
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
770
795
    {
771
796
      update_non_unique_table_error(table_list, "UPDATE", duplicate);
773
798
      return(true);
774
799
    }
775
800
  }
776
 
 
 
801
  select_lex->fix_prepare_information(thd, conds, &fake_conds);
777
802
  return(false);
778
803
}
779
804
 
813
838
int mysql_multi_update_prepare(THD *thd)
814
839
{
815
840
  LEX *lex= thd->lex;
816
 
  TableList *table_list= lex->query_tables;
817
 
  TableList *tl, *leaves;
 
841
  TABLE_LIST *table_list= lex->query_tables;
 
842
  TABLE_LIST *tl, *leaves;
818
843
  List<Item> *fields= &lex->select_lex.item_list;
819
844
  table_map tables_for_update;
820
845
  bool update_view= 0;
823
848
    counter else junk will be assigned here, but then replaced with real
824
849
    count in open_tables()
825
850
  */
826
 
  uint32_t  table_count= lex->table_count;
 
851
  uint  table_count= lex->table_count;
827
852
  const bool using_lock_tables= thd->locked_tables != 0;
828
853
  bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
829
854
  bool need_reopen= false;
867
892
  leaves= lex->select_lex.leaf_tables;
868
893
  for (tl= leaves; tl; tl= tl->next_leaf)
869
894
  {
870
 
    Table *table= tl->table;
 
895
    TABLE *table= tl->table;
871
896
    /* Only set timestamp column if this is not modified */
872
897
    if (table->timestamp_field &&
873
898
        bitmap_is_set(table->write_set,
892
917
      */
893
918
      tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
894
919
      tl->updating= 0;
895
 
      /* Update Table::lock_type accordingly. */
 
920
      /* Update TABLE::lock_type accordingly. */
896
921
      if (!tl->placeholder() && !using_lock_tables)
897
922
        tl->table->reginfo.lock_type= tl->lock_type;
898
923
    }
916
941
      item->cleanup();
917
942
 
918
943
    /* We have to cleanup translation tables of views. */
919
 
    for (TableList *tbl= table_list; tbl; tbl= tbl->next_global)
 
944
    for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
920
945
      tbl->cleanup_items();
921
946
 
922
947
    close_tables_for_reopen(thd, &table_list);
934
959
    if (tl->lock_type != TL_READ &&
935
960
        tl->lock_type != TL_READ_NO_INSERT)
936
961
    {
937
 
      TableList *duplicate;
 
962
      TABLE_LIST *duplicate;
938
963
      if ((duplicate= unique_table(thd, tl, table_list, 0)))
939
964
      {
940
965
        update_non_unique_table_error(table_list, "UPDATE", duplicate);
961
986
*/
962
987
 
963
988
bool mysql_multi_update(THD *thd,
964
 
                        TableList *table_list,
 
989
                        TABLE_LIST *table_list,
965
990
                        List<Item> *fields,
966
991
                        List<Item> *values,
967
992
                        COND *conds,
968
 
                        uint64_t options,
 
993
                        ulonglong options,
969
994
                        enum enum_duplicates handle_duplicates, bool ignore,
970
995
                        SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
971
996
{
978
1003
                                 handle_duplicates, ignore)))
979
1004
    return(true);
980
1005
 
981
 
  thd->abort_on_warning= true;
 
1006
  thd->abort_on_warning= test(thd->variables.sql_mode &
 
1007
                              (MODE_STRICT_TRANS_TABLES |
 
1008
                               MODE_STRICT_ALL_TABLES));
982
1009
 
983
1010
  List<Item> total_list;
984
1011
  res= mysql_select(thd, &select_lex->ref_pointer_array,
985
1012
                      table_list, select_lex->with_wild,
986
1013
                      total_list,
987
 
                      conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
988
 
                      (order_st *)NULL,
 
1014
                      conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
 
1015
                      (ORDER *)NULL,
989
1016
                      options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
990
1017
                      OPTION_SETUP_TABLES_DONE,
991
1018
                      result, unit, select_lex);
1002
1029
}
1003
1030
 
1004
1031
 
1005
 
multi_update::multi_update(TableList *table_list,
1006
 
                           TableList *leaves_list,
 
1032
multi_update::multi_update(TABLE_LIST *table_list,
 
1033
                           TABLE_LIST *leaves_list,
1007
1034
                           List<Item> *field_list, List<Item> *value_list,
1008
1035
                           enum enum_duplicates handle_duplicates_arg,
1009
1036
                           bool ignore_arg)
1019
1046
  Connect fields with tables and create list of tables that are updated
1020
1047
*/
1021
1048
 
1022
 
int multi_update::prepare(List<Item> &not_used_values __attribute__((unused)),
1023
 
                          SELECT_LEX_UNIT *lex_unit __attribute__((unused)))
 
1049
int multi_update::prepare(List<Item> &not_used_values,
 
1050
                          SELECT_LEX_UNIT *lex_unit)
1024
1051
{
1025
 
  TableList *table_ref;
 
1052
  TABLE_LIST *table_ref;
1026
1053
  SQL_LIST update;
1027
1054
  table_map tables_to_update;
1028
1055
  Item_field *item;
1029
1056
  List_iterator_fast<Item> field_it(*fields);
1030
1057
  List_iterator_fast<Item> value_it(*values);
1031
 
  uint32_t i, max_fields;
1032
 
  uint32_t leaf_table_count= 0;
 
1058
  uint i, max_fields;
 
1059
  uint leaf_table_count= 0;
1033
1060
  
1034
1061
  thd->count_cuted_fields= CHECK_FIELD_WARN;
1035
1062
  thd->cuted_fields=0L;
1036
 
  thd->set_proc_info("updating main table");
 
1063
  thd_proc_info(thd, "updating main table");
1037
1064
 
1038
1065
  tables_to_update= get_table_map(fields);
1039
1066
 
1061
1088
  for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1062
1089
  {
1063
1090
    /* TODO: add support of view of join support */
1064
 
    Table *table=table_ref->table;
 
1091
    TABLE *table=table_ref->table;
1065
1092
    leaf_table_count++;
1066
1093
    if (tables_to_update & table->map)
1067
1094
    {
1068
 
      TableList *tl= (TableList*) thd->memdup((char*) table_ref,
 
1095
      TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
1069
1096
                                                sizeof(*tl));
1070
1097
      if (!tl)
1071
1098
        return(1);
1072
 
      update.link_in_list((unsigned char*) tl, (unsigned char**) &tl->next_local);
 
1099
      update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
1073
1100
      tl->shared= table_count++;
1074
1101
      table->no_keyread=1;
1075
1102
      table->covering_keys.clear_all();
1079
1106
 
1080
1107
 
1081
1108
  table_count=  update.elements;
1082
 
  update_tables= (TableList*) update.first;
 
1109
  update_tables= (TABLE_LIST*) update.first;
1083
1110
 
1084
 
  tmp_tables = (Table**) thd->calloc(sizeof(Table *) * table_count);
 
1111
  tmp_tables = (TABLE**) thd->calloc(sizeof(TABLE *) * table_count);
1085
1112
  tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
1086
1113
                                                   table_count);
1087
1114
  fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1103
1130
  while ((item= (Item_field *) field_it++))
1104
1131
  {
1105
1132
    Item *value= value_it++;
1106
 
    uint32_t offset= item->field->table->pos_in_table_list->shared;
 
1133
    uint offset= item->field->table->pos_in_table_list->shared;
1107
1134
    fields_for_table[offset]->push_back(item);
1108
1135
    values_for_table[offset]->push_back(value);
1109
1136
  }
1142
1169
    - Table is not joined to itself.
1143
1170
 
1144
1171
    This function gets information about fields to be updated from
1145
 
    the Table::write_set bitmap.
 
1172
    the TABLE::write_set bitmap.
1146
1173
 
1147
1174
  WARNING
1148
1175
    This code is a bit dependent of how make_join_readinfo() works.
1153
1180
*/
1154
1181
 
1155
1182
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
1156
 
                               TableList *table_ref, TableList *all_tables)
 
1183
                               TABLE_LIST *table_ref, TABLE_LIST *all_tables)
1157
1184
{
1158
 
  Table *table= join_tab->table;
 
1185
  TABLE *table= join_tab->table;
1159
1186
  if (unique_table(thd, table_ref, all_tables, 0))
1160
1187
    return 0;
1161
1188
  switch (join_tab->type) {
1195
1222
bool
1196
1223
multi_update::initialize_tables(JOIN *join)
1197
1224
{
1198
 
  TableList *table_ref;
 
1225
  TABLE_LIST *table_ref;
1199
1226
  
1200
1227
  if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
1201
1228
    return(1);
1208
1235
  /* Create a temporary table for keys to all tables, except main table */
1209
1236
  for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
1210
1237
  {
1211
 
    Table *table=table_ref->table;
1212
 
    uint32_t cnt= table_ref->shared;
 
1238
    TABLE *table=table_ref->table;
 
1239
    uint cnt= table_ref->shared;
1213
1240
    List<Item> temp_fields;
1214
 
    order_st     group;
 
1241
    ORDER     group;
1215
1242
    TMP_TABLE_PARAM *tmp_param;
1216
1243
 
1217
1244
    table->mark_columns_needed_for_update();
1237
1264
      OPTION condition.
1238
1265
    */
1239
1266
 
1240
 
    List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1241
 
    Table *tbl= table;
 
1267
    List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
 
1268
    TABLE *tbl= table;
1242
1269
    do
1243
1270
    {
1244
1271
      Field_string *field= new Field_string(tbl->file->ref_length, 0,
1245
1272
                                            tbl->alias, &my_charset_bin);
1246
 
#ifdef OLD
1247
 
      Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1248
 
                                                  tbl->alias, tbl->s, &my_charset_bin);
1249
 
#endif
1250
1273
      if (!field)
1251
1274
        return(1);
1252
1275
      field->init(tbl);
1254
1277
        The field will be converted to varstring when creating tmp table if
1255
1278
        table to be updated was created by mysql 4.1. Deny this.
1256
1279
      */
 
1280
      field->can_alter_field_type= 0;
1257
1281
      Item_field *ifield= new Item_field((Field *) field);
1258
1282
      if (!ifield)
1259
1283
         return(1);
1265
1289
    temp_fields.concat(fields_for_table[cnt]);
1266
1290
 
1267
1291
    /* Make an unique key over the first field to avoid duplicated updates */
1268
 
    memset(&group, 0, sizeof(group));
 
1292
    bzero((char*) &group, sizeof(group));
1269
1293
    group.asc= 1;
1270
1294
    group.item= (Item**) temp_fields.head_ref();
1271
1295
 
1276
1300
    if (!(tmp_tables[cnt]=create_tmp_table(thd,
1277
1301
                                           tmp_param,
1278
1302
                                           temp_fields,
1279
 
                                           (order_st*) &group, 0, 0,
 
1303
                                           (ORDER*) &group, 0, 0,
1280
1304
                                           TMP_TABLE_ALL_COLUMNS,
1281
1305
                                           HA_POS_ERROR,
1282
1306
                                           (char *) "")))
1289
1313
 
1290
1314
multi_update::~multi_update()
1291
1315
{
1292
 
  TableList *table;
 
1316
  TABLE_LIST *table;
1293
1317
  for (table= update_tables ; table; table= table->next_local)
1294
1318
  {
1295
1319
    table->table->no_keyread= table->table->no_cache= 0;
1299
1323
 
1300
1324
  if (tmp_tables)
1301
1325
  {
1302
 
    for (uint32_t cnt = 0; cnt < table_count; cnt++)
 
1326
    for (uint cnt = 0; cnt < table_count; cnt++)
1303
1327
    {
1304
1328
      if (tmp_tables[cnt])
1305
1329
      {
1306
 
        tmp_tables[cnt]->free_tmp_table(thd);
 
1330
        free_tmp_table(thd, tmp_tables[cnt]);
1307
1331
        tmp_table_param[cnt].cleanup();
1308
1332
      }
1309
1333
    }
1311
1335
  if (copy_field)
1312
1336
    delete [] copy_field;
1313
1337
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          // Restore this setting
1314
 
  assert(trans_safe || !updated ||
 
1338
  assert(trans_safe || !updated || 
1315
1339
              thd->transaction.all.modified_non_trans_table);
1316
1340
}
1317
1341
 
1318
1342
 
1319
 
bool multi_update::send_data(List<Item> &not_used_values __attribute__((unused)))
 
1343
bool multi_update::send_data(List<Item> &not_used_values)
1320
1344
{
1321
 
  TableList *cur_table;
 
1345
  TABLE_LIST *cur_table;
1322
1346
  
1323
1347
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1324
1348
  {
1325
 
    Table *table= cur_table->table;
1326
 
    uint32_t offset= cur_table->shared;
 
1349
    TABLE *table= cur_table->table;
 
1350
    uint offset= cur_table->shared;
1327
1351
    /*
1328
1352
      Check if we are using outer join and we didn't find the row
1329
1353
      or if we have already updated this row in the previous call to this
1358
1382
        return(1);
1359
1383
 
1360
1384
      found++;
1361
 
      if (!can_compare_record || table->compare_record())
 
1385
      if (!can_compare_record || compare_record(table))
1362
1386
      {
1363
1387
        int error;
1364
1388
        if (!updated++)
1414
1438
    else
1415
1439
    {
1416
1440
      int error;
1417
 
      Table *tmp_table= tmp_tables[offset];
 
1441
      TABLE *tmp_table= tmp_tables[offset];
1418
1442
      /*
1419
1443
       For updatable VIEW store rowid of the updated table and
1420
1444
       rowids of tables used in the CHECK OPTION condition.
1421
1445
      */
1422
 
      uint32_t field_num= 0;
1423
 
      List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1424
 
      Table *tbl= table;
 
1446
      uint field_num= 0;
 
1447
      List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
 
1448
      TABLE *tbl= table;
1425
1449
      do
1426
1450
      {
1427
1451
        tbl->file->position(tbl->record[0]);
1428
 
        memcpy(tmp_table->field[field_num]->ptr,
1429
 
               tbl->file->ref, tbl->file->ref_length);
 
1452
        memcpy((char*) tmp_table->field[field_num]->ptr,
 
1453
               (char*) tbl->file->ref, tbl->file->ref_length);
1430
1454
        field_num++;
1431
1455
      } while ((tbl= tbl_it++));
1432
1456
 
1456
1480
}
1457
1481
 
1458
1482
 
1459
 
void multi_update::send_error(uint32_t errcode,const char *err)
 
1483
void multi_update::send_error(uint errcode,const char *err)
1460
1484
{
1461
1485
  /* First send error what ever it is ... */
1462
1486
  my_error(errcode, MYF(0), err);
1484
1508
         todo/fixme: do_update() is never called with the arg 1.
1485
1509
         should it change the signature to become argless?
1486
1510
      */
1487
 
      do_updates();
 
1511
      VOID(do_updates());
1488
1512
    }
1489
1513
  }
1490
1514
  if (thd->transaction.stmt.modified_non_trans_table)
1512
1536
 
1513
1537
int multi_update::do_updates()
1514
1538
{
1515
 
  TableList *cur_table;
 
1539
  TABLE_LIST *cur_table;
1516
1540
  int local_error= 0;
1517
1541
  ha_rows org_updated;
1518
 
  Table *table, *tmp_table;
1519
 
  List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
 
1542
  TABLE *table, *tmp_table;
 
1543
  List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
1520
1544
  
1521
1545
  do_update= 0;                                 // Don't retry this function
1522
1546
  if (!found)
1524
1548
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1525
1549
  {
1526
1550
    bool can_compare_record;
1527
 
    uint32_t offset= cur_table->shared;
 
1551
    uint offset= cur_table->shared;
1528
1552
 
1529
1553
    table = cur_table->table;
1530
1554
    if (table == table_to_update)
1536
1560
    table->file->extra(HA_EXTRA_NO_CACHE);
1537
1561
 
1538
1562
    check_opt_it.rewind();
1539
 
    while(Table *tbl= check_opt_it++)
 
1563
    while(TABLE *tbl= check_opt_it++)
1540
1564
    {
1541
1565
      if (tbl->file->ha_rnd_init(1))
1542
1566
        goto err;
1580
1604
 
1581
1605
      /* call rnd_pos() using rowids from temporary table */
1582
1606
      check_opt_it.rewind();
1583
 
      Table *tbl= table;
1584
 
      uint32_t field_num= 0;
 
1607
      TABLE *tbl= table;
 
1608
      uint field_num= 0;
1585
1609
      do
1586
1610
      {
1587
1611
        if((local_error=
1588
1612
              tbl->file->rnd_pos(tbl->record[0],
1589
 
                                (unsigned char *) tmp_table->field[field_num]->ptr)))
 
1613
                                (uchar *) tmp_table->field[field_num]->ptr)))
1590
1614
          goto err;
1591
1615
        field_num++;
1592
1616
      } while((tbl= check_opt_it++));
1600
1624
           copy_field_ptr++)
1601
1625
        (*copy_field_ptr->do_copy)(copy_field_ptr);
1602
1626
 
1603
 
      if (!can_compare_record || table->compare_record())
 
1627
      if (!can_compare_record || compare_record(table))
1604
1628
      {
1605
1629
        if ((local_error=table->file->ha_update_row(table->record[1],
1606
1630
                                                    table->record[0])) &&
1630
1654
    (void) table->file->ha_rnd_end();
1631
1655
    (void) tmp_table->file->ha_rnd_end();
1632
1656
    check_opt_it.rewind();
1633
 
    while (Table *tbl= check_opt_it++)
 
1657
    while (TABLE *tbl= check_opt_it++)
1634
1658
        tbl->file->ha_rnd_end();
1635
1659
 
1636
1660
  }
1645
1669
  (void) table->file->ha_rnd_end();
1646
1670
  (void) tmp_table->file->ha_rnd_end();
1647
1671
  check_opt_it.rewind();
1648
 
  while (Table *tbl= check_opt_it++)
 
1672
  while (TABLE *tbl= check_opt_it++)
1649
1673
      tbl->file->ha_rnd_end();
1650
1674
 
1651
1675
  if (updated != org_updated)
1667
1691
bool multi_update::send_eof()
1668
1692
{
1669
1693
  char buff[STRING_BUFFER_USUAL_SIZE];
1670
 
  uint64_t id;
 
1694
  ulonglong id;
1671
1695
  THD::killed_state killed_status= THD::NOT_KILLED;
1672
1696
  
1673
 
  thd->set_proc_info("updating reference tables");
 
1697
  thd_proc_info(thd, "updating reference tables");
1674
1698
 
1675
1699
  /* 
1676
1700
     Does updates for the last n - 1 tables, returns 0 if ok;
1682
1706
    later carried out killing should not affect binlogging.
1683
1707
  */
1684
1708
  killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
1685
 
  thd->set_proc_info("end");
 
1709
  thd_proc_info(thd, "end");
1686
1710
 
1687
1711
  /*
1688
1712
    Write the SQL statement to the binlog if we updated