~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_update.cc

  • Committer: Jay Pipes
  • Date: 2008-07-17 19:43:08 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717194308-l9i4ti57gikm2qbv
Phase 1 removal of DBUG in mysys

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