~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

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