~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2008-08-04 22:01:39 UTC
  • mto: (261.1.4 drizzle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804220139-fy862jc9lykayvka
Moved libdrizzle.ver.in to libdrizzle.ver.

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>
 
21
 
 
22
#include "mysql_priv.h"
 
23
#include "sql_select.h"
23
24
#include <drizzled/drizzled_error_messages.h>
24
25
 
 
26
/* Return 0 if row hasn't changed */
 
27
 
 
28
bool compare_record(TABLE *table)
 
29
{
 
30
  if (table->s->blob_fields + table->s->varchar_fields == 0)
 
31
    return cmp_record(table,record[1]);
 
32
  /* Compare null bits */
 
33
  if (memcmp(table->null_flags,
 
34
             table->null_flags+table->s->rec_buff_length,
 
35
             table->s->null_bytes))
 
36
    return true;                                // Diff in NULL value
 
37
  /* Compare updated fields */
 
38
  for (Field **ptr= table->field ; *ptr ; ptr++)
 
39
  {
 
40
    if (bitmap_is_set(table->write_set, (*ptr)->field_index) &&
 
41
        (*ptr)->cmp_binary_offset(table->s->rec_buff_length))
 
42
      return true;
 
43
  }
 
44
  return false;
 
45
}
 
46
 
 
47
 
25
48
/*
26
49
  check that all fields are real fields
27
50
 
71
94
  @param[in] table   table
72
95
*/
73
96
 
74
 
static void prepare_record_for_error_message(int error, Table *table)
 
97
static void prepare_record_for_error_message(int error, TABLE *table)
75
98
{
76
99
  Field **field_p;
77
100
  Field *field;
78
 
  uint32_t keynr;
 
101
  uint keynr;
79
102
  MY_BITMAP unique_map; /* Fields in offended unique. */
80
103
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
81
104
  
136
159
    fields              fields for update
137
160
    values              values of fields for update
138
161
    conds               WHERE clause expression
139
 
    order_num           number of elemen in order_st BY clause
140
 
    order               order_st BY clause list
 
162
    order_num           number of elemen in ORDER BY clause
 
163
    order               ORDER BY clause list
141
164
    limit               limit clause
142
165
    handle_duplicates   how to handle duplicates
143
166
 
149
172
*/
150
173
 
151
174
int mysql_update(THD *thd,
152
 
                 TableList *table_list,
 
175
                 TABLE_LIST *table_list,
153
176
                 List<Item> &fields,
154
177
                 List<Item> &values,
155
178
                 COND *conds,
156
 
                 uint32_t order_num, order_st *order,
 
179
                 uint order_num, ORDER *order,
157
180
                 ha_rows limit,
158
181
                 enum enum_duplicates handle_duplicates __attribute__((unused)),
159
182
                 bool ignore)
165
188
  int           error, loc_error;
166
189
  uint          used_index= MAX_KEY, dup_key_found;
167
190
  bool          need_sort= true;
168
 
  uint32_t          table_count= 0;
 
191
  uint          table_count= 0;
169
192
  ha_rows       updated, found;
170
193
  key_map       old_covering_keys;
171
 
  Table         *table;
 
194
  TABLE         *table;
172
195
  SQL_SELECT    *select;
173
196
  READ_RECORD   info;
174
197
  SELECT_LEX    *select_lex= &thd->lex->select_lex;
194
217
       mysql_handle_derived(thd->lex, &mysql_derived_filling)))
195
218
    return(1);
196
219
 
197
 
  DRIZZLE_UPDATE_START();
 
220
  MYSQL_UPDATE_START();
198
221
  thd_proc_info(thd, "init");
199
222
  table= table_list->table;
200
223
 
233
256
  if (select_lex->inner_refs_list.elements &&
234
257
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
235
258
  {
236
 
    DRIZZLE_UPDATE_END();
 
259
    MYSQL_UPDATE_END();
237
260
    return(-1);
238
261
  }
239
262
 
269
292
    free_underlaid_joins(thd, select_lex);
270
293
    if (error)
271
294
      goto abort;                               // Error in where
272
 
    DRIZZLE_UPDATE_END();
 
295
    MYSQL_UPDATE_END();
273
296
    my_ok(thd);                         // No matching records
274
297
    return(0);
275
298
  }
330
353
    if (order && (need_sort || used_key_is_modified))
331
354
    {
332
355
      /*
333
 
        Doing an order_st BY;  Let filesort find and sort the rows we are going
 
356
        Doing an ORDER BY;  Let filesort find and sort the rows we are going
334
357
        to update
335
358
        NOTE: filesort will call table->prepare_for_position()
336
359
      */
337
 
      uint32_t         length= 0;
 
360
      uint         length= 0;
338
361
      SORT_FIELD  *sortorder;
339
362
      ha_rows examined_rows;
340
363
 
461
484
  thd_proc_info(thd, "Updating");
462
485
 
463
486
  transactional_table= table->file->has_transactions();
464
 
  thd->abort_on_warning= test(!ignore);
 
487
  thd->abort_on_warning= test(!ignore &&
 
488
                              (thd->variables.sql_mode &
 
489
                               (MODE_STRICT_TRANS_TABLES |
 
490
                                MODE_STRICT_ALL_TABLES)));
465
491
  will_batch= !table->file->start_bulk_update();
466
492
 
467
493
  /*
493
519
 
494
520
      found++;
495
521
 
496
 
      if (!can_compare_record || table->compare_record())
 
522
      if (!can_compare_record || compare_record(table))
497
523
      {
498
524
        if (will_batch)
499
525
        {
651
677
  end_read_record(&info);
652
678
  delete select;
653
679
  thd_proc_info(thd, "end");
654
 
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
680
  VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
655
681
 
656
682
  /*
657
683
    error < 0 means really no error at all: we processed all rows until the
686
712
  id= thd->arg_of_last_insert_id_function ?
687
713
    thd->first_successful_insert_id_in_prev_stmt : 0;
688
714
 
689
 
  DRIZZLE_UPDATE_END();
 
715
  MYSQL_UPDATE_END();
690
716
  if (error < 0)
691
717
  {
692
718
    char buff[STRING_BUFFER_USUAL_SIZE];
711
737
  thd->abort_on_warning= 0;
712
738
 
713
739
abort:
714
 
  DRIZZLE_UPDATE_END();
 
740
  MYSQL_UPDATE_END();
715
741
  return(1);
716
742
}
717
743
 
723
749
    thd                 - thread handler
724
750
    table_list          - global/local table list
725
751
    conds               - conditions
726
 
    order_num           - number of order_st BY list entries
727
 
    order               - order_st BY clause list
 
752
    order_num           - number of ORDER BY list entries
 
753
    order               - ORDER BY clause list
728
754
 
729
755
  RETURN VALUE
730
756
    false OK
731
757
    true  error
732
758
*/
733
 
bool mysql_prepare_update(THD *thd, TableList *table_list,
734
 
                         Item **conds, uint32_t order_num, order_st *order)
 
759
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
 
760
                         Item **conds, uint order_num, ORDER *order)
735
761
{
736
762
  List<Item> all_fields;
737
763
  SELECT_LEX *select_lex= &thd->lex->select_lex;
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);
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)
1022
1050
int multi_update::prepare(List<Item> &not_used_values __attribute__((unused)),
1023
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,
1265
1293
    temp_fields.concat(fields_for_table[cnt]);
1266
1294
 
1267
1295
    /* Make an unique key over the first field to avoid duplicated updates */
1268
 
    memset(&group, 0, sizeof(group));
 
1296
    memset((char*) &group, 0, sizeof(group));
1269
1297
    group.asc= 1;
1270
1298
    group.item= (Item**) temp_fields.head_ref();
1271
1299
 
1276
1304
    if (!(tmp_tables[cnt]=create_tmp_table(thd,
1277
1305
                                           tmp_param,
1278
1306
                                           temp_fields,
1279
 
                                           (order_st*) &group, 0, 0,
 
1307
                                           (ORDER*) &group, 0, 0,
1280
1308
                                           TMP_TABLE_ALL_COLUMNS,
1281
1309
                                           HA_POS_ERROR,
1282
1310
                                           (char *) "")))
1289
1317
 
1290
1318
multi_update::~multi_update()
1291
1319
{
1292
 
  TableList *table;
 
1320
  TABLE_LIST *table;
1293
1321
  for (table= update_tables ; table; table= table->next_local)
1294
1322
  {
1295
1323
    table->table->no_keyread= table->table->no_cache= 0;
1299
1327
 
1300
1328
  if (tmp_tables)
1301
1329
  {
1302
 
    for (uint32_t cnt = 0; cnt < table_count; cnt++)
 
1330
    for (uint cnt = 0; cnt < table_count; cnt++)
1303
1331
    {
1304
1332
      if (tmp_tables[cnt])
1305
1333
      {
1306
 
        tmp_tables[cnt]->free_tmp_table(thd);
 
1334
        free_tmp_table(thd, tmp_tables[cnt]);
1307
1335
        tmp_table_param[cnt].cleanup();
1308
1336
      }
1309
1337
    }
1318
1346
 
1319
1347
bool multi_update::send_data(List<Item> &not_used_values __attribute__((unused)))
1320
1348
{
1321
 
  TableList *cur_table;
 
1349
  TABLE_LIST *cur_table;
1322
1350
  
1323
1351
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1324
1352
  {
1325
 
    Table *table= cur_table->table;
1326
 
    uint32_t offset= cur_table->shared;
 
1353
    TABLE *table= cur_table->table;
 
1354
    uint offset= cur_table->shared;
1327
1355
    /*
1328
1356
      Check if we are using outer join and we didn't find the row
1329
1357
      or if we have already updated this row in the previous call to this
1358
1386
        return(1);
1359
1387
 
1360
1388
      found++;
1361
 
      if (!can_compare_record || table->compare_record())
 
1389
      if (!can_compare_record || compare_record(table))
1362
1390
      {
1363
1391
        int error;
1364
1392
        if (!updated++)
1414
1442
    else
1415
1443
    {
1416
1444
      int error;
1417
 
      Table *tmp_table= tmp_tables[offset];
 
1445
      TABLE *tmp_table= tmp_tables[offset];
1418
1446
      /*
1419
1447
       For updatable VIEW store rowid of the updated table and
1420
1448
       rowids of tables used in the CHECK OPTION condition.
1421
1449
      */
1422
 
      uint32_t field_num= 0;
1423
 
      List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1424
 
      Table *tbl= table;
 
1450
      uint field_num= 0;
 
1451
      List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
 
1452
      TABLE *tbl= table;
1425
1453
      do
1426
1454
      {
1427
1455
        tbl->file->position(tbl->record[0]);
1428
 
        memcpy(tmp_table->field[field_num]->ptr,
1429
 
               tbl->file->ref, tbl->file->ref_length);
 
1456
        memcpy((char*) tmp_table->field[field_num]->ptr,
 
1457
               (char*) tbl->file->ref, tbl->file->ref_length);
1430
1458
        field_num++;
1431
1459
      } while ((tbl= tbl_it++));
1432
1460
 
1456
1484
}
1457
1485
 
1458
1486
 
1459
 
void multi_update::send_error(uint32_t errcode,const char *err)
 
1487
void multi_update::send_error(uint errcode,const char *err)
1460
1488
{
1461
1489
  /* First send error what ever it is ... */
1462
1490
  my_error(errcode, MYF(0), err);
1484
1512
         todo/fixme: do_update() is never called with the arg 1.
1485
1513
         should it change the signature to become argless?
1486
1514
      */
1487
 
      do_updates();
 
1515
      VOID(do_updates());
1488
1516
    }
1489
1517
  }
1490
1518
  if (thd->transaction.stmt.modified_non_trans_table)
1512
1540
 
1513
1541
int multi_update::do_updates()
1514
1542
{
1515
 
  TableList *cur_table;
 
1543
  TABLE_LIST *cur_table;
1516
1544
  int local_error= 0;
1517
1545
  ha_rows org_updated;
1518
 
  Table *table, *tmp_table;
1519
 
  List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
 
1546
  TABLE *table, *tmp_table;
 
1547
  List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
1520
1548
  
1521
1549
  do_update= 0;                                 // Don't retry this function
1522
1550
  if (!found)
1524
1552
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1525
1553
  {
1526
1554
    bool can_compare_record;
1527
 
    uint32_t offset= cur_table->shared;
 
1555
    uint offset= cur_table->shared;
1528
1556
 
1529
1557
    table = cur_table->table;
1530
1558
    if (table == table_to_update)
1536
1564
    table->file->extra(HA_EXTRA_NO_CACHE);
1537
1565
 
1538
1566
    check_opt_it.rewind();
1539
 
    while(Table *tbl= check_opt_it++)
 
1567
    while(TABLE *tbl= check_opt_it++)
1540
1568
    {
1541
1569
      if (tbl->file->ha_rnd_init(1))
1542
1570
        goto err;
1580
1608
 
1581
1609
      /* call rnd_pos() using rowids from temporary table */
1582
1610
      check_opt_it.rewind();
1583
 
      Table *tbl= table;
1584
 
      uint32_t field_num= 0;
 
1611
      TABLE *tbl= table;
 
1612
      uint field_num= 0;
1585
1613
      do
1586
1614
      {
1587
1615
        if((local_error=
1588
1616
              tbl->file->rnd_pos(tbl->record[0],
1589
 
                                (unsigned char *) tmp_table->field[field_num]->ptr)))
 
1617
                                (uchar *) tmp_table->field[field_num]->ptr)))
1590
1618
          goto err;
1591
1619
        field_num++;
1592
1620
      } while((tbl= check_opt_it++));
1600
1628
           copy_field_ptr++)
1601
1629
        (*copy_field_ptr->do_copy)(copy_field_ptr);
1602
1630
 
1603
 
      if (!can_compare_record || table->compare_record())
 
1631
      if (!can_compare_record || compare_record(table))
1604
1632
      {
1605
1633
        if ((local_error=table->file->ha_update_row(table->record[1],
1606
1634
                                                    table->record[0])) &&
1630
1658
    (void) table->file->ha_rnd_end();
1631
1659
    (void) tmp_table->file->ha_rnd_end();
1632
1660
    check_opt_it.rewind();
1633
 
    while (Table *tbl= check_opt_it++)
 
1661
    while (TABLE *tbl= check_opt_it++)
1634
1662
        tbl->file->ha_rnd_end();
1635
1663
 
1636
1664
  }
1645
1673
  (void) table->file->ha_rnd_end();
1646
1674
  (void) tmp_table->file->ha_rnd_end();
1647
1675
  check_opt_it.rewind();
1648
 
  while (Table *tbl= check_opt_it++)
 
1676
  while (TABLE *tbl= check_opt_it++)
1649
1677
      tbl->file->ha_rnd_end();
1650
1678
 
1651
1679
  if (updated != org_updated)