~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_update.cc

  • Committer: Monty Taylor
  • Date: 2008-07-09 16:42:25 UTC
  • mto: (77.6.1 glibclient-merge)
  • mto: This revision was merged to the branch mainline in revision 112.
  • Revision ID: monty@inaugust.com-20080709164225-2r6n4j98nhxh031l
Moved test to tests... 

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/error.h>
24
 
#include <drizzled/probes.h>
25
 
#include <drizzled/sql_base.h>
26
 
#include <drizzled/field/timestamp.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
 
27
46
 
28
47
/*
29
48
  check that all fields are real fields
30
49
 
31
50
  SYNOPSIS
32
51
    check_fields()
33
 
    session             thread handler
 
52
    thd             thread handler
34
53
    items           Items for check
35
54
 
36
55
  RETURN
38
57
    false Items are OK
39
58
*/
40
59
 
41
 
static bool check_fields(Session *session, List<Item> &items)
 
60
static bool check_fields(THD *thd, List<Item> &items)
42
61
{
43
62
  List_iterator<Item> it(items);
44
63
  Item *item;
56
75
      we make temporary copy of Item_field, to avoid influence of changing
57
76
      result_field on Item_ref which refer on this field
58
77
    */
59
 
    session->change_item_tree(it.ref(), new Item_field(session, field));
 
78
    thd->change_item_tree(it.ref(), new Item_field(thd, field));
60
79
  }
61
80
  return false;
62
81
}
74
93
  @param[in] table   table
75
94
*/
76
95
 
77
 
static void prepare_record_for_error_message(int error, Table *table)
 
96
static void prepare_record_for_error_message(int error, TABLE *table)
78
97
{
79
98
  Field **field_p;
80
99
  Field *field;
81
 
  uint32_t keynr;
 
100
  uint keynr;
82
101
  MY_BITMAP unique_map; /* Fields in offended unique. */
83
102
  my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)];
84
 
 
 
103
  
85
104
  /*
86
105
    Only duplicate key errors print the key value.
87
106
    If storage engine does always read all columns, we have the value alraedy.
135
154
 
136
155
  SYNOPSIS
137
156
    mysql_update()
138
 
    session                     thread handler
 
157
    thd                 thread handler
139
158
    fields              fields for update
140
159
    values              values of fields for update
141
160
    conds               WHERE clause expression
142
 
    order_num           number of elemen in order_st BY clause
143
 
    order               order_st BY clause list
 
161
    order_num           number of elemen in ORDER BY clause
 
162
    order               ORDER BY clause list
144
163
    limit               limit clause
145
164
    handle_duplicates   how to handle duplicates
146
165
 
151
170
    1  - error
152
171
*/
153
172
 
154
 
int mysql_update(Session *session, TableList *table_list,
155
 
                 List<Item> &fields, List<Item> &values, COND *conds,
156
 
                 uint32_t order_num, order_st *order,
157
 
                 ha_rows limit, enum enum_duplicates,
 
173
int mysql_update(THD *thd,
 
174
                 TABLE_LIST *table_list,
 
175
                 List<Item> &fields,
 
176
                 List<Item> &values,
 
177
                 COND *conds,
 
178
                 uint order_num, ORDER *order,
 
179
                 ha_rows limit,
 
180
                 enum enum_duplicates handle_duplicates __attribute__((__unused__)),
158
181
                 bool ignore)
159
182
{
160
183
  bool          using_limit= limit != HA_POS_ERROR;
161
 
  bool          safe_update= test(session->options & OPTION_SAFE_UPDATES);
 
184
  bool          safe_update= test(thd->options & OPTION_SAFE_UPDATES);
162
185
  bool          used_key_is_modified, transactional_table, will_batch;
163
186
  bool          can_compare_record;
164
187
  int           error, loc_error;
165
188
  uint          used_index= MAX_KEY, dup_key_found;
166
189
  bool          need_sort= true;
167
 
  uint32_t          table_count= 0;
 
190
  uint          table_count= 0;
168
191
  ha_rows       updated, found;
169
192
  key_map       old_covering_keys;
170
 
  Table         *table;
 
193
  TABLE         *table;
171
194
  SQL_SELECT    *select;
172
195
  READ_RECORD   info;
173
 
  SELECT_LEX    *select_lex= &session->lex->select_lex;
 
196
  SELECT_LEX    *select_lex= &thd->lex->select_lex;
174
197
  bool          need_reopen;
175
 
  uint64_t     id;
 
198
  ulonglong     id;
176
199
  List<Item> all_fields;
177
 
  Session::killed_state killed_status= Session::NOT_KILLED;
178
 
 
 
200
  THD::killed_state killed_status= THD::NOT_KILLED;
 
201
  
179
202
  for ( ; ; )
180
203
  {
181
 
    if (open_tables(session, &table_list, &table_count, 0))
 
204
    if (open_tables(thd, &table_list, &table_count, 0))
182
205
      return(1);
183
206
 
184
 
    if (!lock_tables(session, table_list, table_count, &need_reopen))
 
207
    if (!lock_tables(thd, table_list, table_count, &need_reopen))
185
208
      break;
186
209
    if (!need_reopen)
187
210
      return(1);
188
 
    close_tables_for_reopen(session, &table_list);
 
211
    close_tables_for_reopen(thd, &table_list);
189
212
  }
190
213
 
191
 
  if (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
192
 
      (session->fill_derived_tables() &&
193
 
       mysql_handle_derived(session->lex, &mysql_derived_filling)))
 
214
  if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
 
215
      (thd->fill_derived_tables() &&
 
216
       mysql_handle_derived(thd->lex, &mysql_derived_filling)))
194
217
    return(1);
195
218
 
196
 
  DRIZZLE_UPDATE_START();
197
 
  session->set_proc_info("init");
 
219
  MYSQL_UPDATE_START();
 
220
  thd_proc_info(thd, "init");
198
221
  table= table_list->table;
199
222
 
200
223
  /* Calculate "table->covering_keys" based on the WHERE */
201
224
  table->covering_keys= table->s->keys_in_use;
202
225
  table->quick_keys.clear_all();
203
226
 
204
 
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
 
227
  if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
205
228
    goto abort;
206
229
 
207
230
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
208
231
  /* Check the fields we are going to modify */
209
 
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
 
232
  if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
210
233
    goto abort;                               /* purecov: inspected */
211
234
  if (table->timestamp_field)
212
235
  {
223
246
    }
224
247
  }
225
248
 
226
 
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
 
249
  if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
227
250
  {
228
 
    free_underlaid_joins(session, select_lex);
 
251
    free_underlaid_joins(thd, select_lex);
229
252
    goto abort;                               /* purecov: inspected */
230
253
  }
231
254
 
232
255
  if (select_lex->inner_refs_list.elements &&
233
 
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
 
256
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
234
257
  {
235
 
    DRIZZLE_UPDATE_END();
 
258
    MYSQL_UPDATE_END();
236
259
    return(-1);
237
260
  }
238
261
 
239
262
  if (conds)
240
263
  {
241
264
    Item::cond_result cond_value;
242
 
    conds= remove_eq_conds(session, conds, &cond_value);
 
265
    conds= remove_eq_conds(thd, conds, &cond_value);
243
266
    if (cond_value == Item::COND_FALSE)
244
267
      limit= 0;                                   // Impossible WHERE
245
268
  }
262
285
 
263
286
  select= make_select(table, 0, 0, conds, 0, &error);
264
287
  if (error || !limit ||
265
 
      (select && select->check_quick(session, safe_update, limit)))
 
288
      (select && select->check_quick(thd, safe_update, limit)))
266
289
  {
267
290
    delete select;
268
 
    free_underlaid_joins(session, select_lex);
 
291
    free_underlaid_joins(thd, select_lex);
269
292
    if (error)
270
293
      goto abort;                               // Error in where
271
 
    DRIZZLE_UPDATE_END();
272
 
    my_ok(session);                             // No matching records
 
294
    MYSQL_UPDATE_END();
 
295
    my_ok(thd);                         // No matching records
273
296
    return(0);
274
297
  }
275
298
  if (!select && limit != HA_POS_ERROR)
280
303
  /* If running in safe sql mode, don't allow updates without keys */
281
304
  if (table->quick_keys.is_clear_all())
282
305
  {
283
 
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
306
    thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
284
307
    if (safe_update && !using_limit)
285
308
    {
286
309
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
292
315
  table->mark_columns_needed_for_update();
293
316
 
294
317
  /* Check if we are modifying a key that we are used to search with */
295
 
 
 
318
  
296
319
  if (select && select->quick)
297
320
  {
298
321
    used_index= select->quick->index;
329
352
    if (order && (need_sort || used_key_is_modified))
330
353
    {
331
354
      /*
332
 
        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
333
356
        to update
334
357
        NOTE: filesort will call table->prepare_for_position()
335
358
      */
336
 
      uint32_t         length= 0;
 
359
      uint         length= 0;
337
360
      SORT_FIELD  *sortorder;
338
361
      ha_rows examined_rows;
339
362
 
340
 
      table->sort.io_cache = new IO_CACHE;
341
 
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
342
 
 
 
363
      table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
 
364
                                                    MYF(MY_FAE | MY_ZEROFILL));
343
365
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
344
 
          (table->sort.found_records= filesort(session, table, sortorder, length,
 
366
          (table->sort.found_records= filesort(thd, table, sortorder, length,
345
367
                                               select, limit, 1,
346
368
                                               &examined_rows))
347
369
          == HA_POS_ERROR)
364
386
      */
365
387
 
366
388
      IO_CACHE tempfile;
367
 
      if (open_cached_file(&tempfile, drizzle_tmpdir,TEMP_PREFIX,
 
389
      if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
368
390
                           DISK_BUFFER_SIZE, MYF(MY_WME)))
369
391
        goto err;
370
392
 
385
407
      */
386
408
 
387
409
      if (used_index == MAX_KEY || (select && select->quick))
388
 
        init_read_record(&info,session,table,select,0,1);
 
410
        init_read_record(&info,thd,table,select,0,1);
389
411
      else
390
 
        init_read_record_idx(&info, session, table, 1, used_index);
 
412
        init_read_record_idx(&info, thd, table, 1, used_index);
391
413
 
392
 
      session->set_proc_info("Searching rows for update");
 
414
      thd_proc_info(thd, "Searching rows for update");
393
415
      ha_rows tmp_limit= limit;
394
416
 
395
 
      while (!(error=info.read_record(&info)) && !session->killed)
 
417
      while (!(error=info.read_record(&info)) && !thd->killed)
396
418
      {
397
419
        if (!(select && select->skip_record()))
398
420
        {
415
437
        else
416
438
          table->file->unlock_row();
417
439
      }
418
 
      if (session->killed && !error)
 
440
      if (thd->killed && !error)
419
441
        error= 1;                               // Aborted
420
442
      limit= tmp_limit;
421
443
      table->file->try_semi_consistent_read(0);
422
444
      end_read_record(&info);
423
 
 
 
445
     
424
446
      /* Change select to use tempfile */
425
447
      if (select)
426
448
      {
447
469
 
448
470
  if (ignore)
449
471
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
450
 
 
 
472
  
451
473
  if (select && select->quick && select->quick->reset())
452
474
    goto err;
453
475
  table->file->try_semi_consistent_read(1);
454
 
  init_read_record(&info,session,table,select,0,1);
 
476
  init_read_record(&info,thd,table,select,0,1);
455
477
 
456
478
  updated= found= 0;
457
479
  /* Generate an error when trying to set a NOT NULL field to NULL. */
458
 
  session->count_cuted_fields= ignore ? CHECK_FIELD_WARN
 
480
  thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
459
481
                                  : CHECK_FIELD_ERROR_FOR_NULL;
460
 
  session->cuted_fields=0L;
461
 
  session->set_proc_info("Updating");
 
482
  thd->cuted_fields=0L;
 
483
  thd_proc_info(thd, "Updating");
462
484
 
463
485
  transactional_table= table->file->has_transactions();
464
 
  session->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
  /*
480
505
                         HA_PARTIAL_COLUMN_READ) ||
481
506
                       bitmap_is_subset(table->write_set, table->read_set));
482
507
 
483
 
  while (!(error=info.read_record(&info)) && !session->killed)
 
508
  while (!(error=info.read_record(&info)) && !thd->killed)
484
509
  {
485
510
    if (!(select && select->skip_record()))
486
511
    {
488
513
        continue;  /* repeat the read of the same row if it still exists */
489
514
 
490
515
      store_record(table,record[1]);
491
 
      if (fill_record(session, fields, values, 0))
 
516
      if (fill_record(thd, fields, values, 0))
492
517
        break; /* purecov: inspected */
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
        {
506
531
 
507
532
            1) is covered by exec_bulk_update calls.
508
533
            2) and 3) is handled by the bulk_update_row method.
509
 
 
 
534
            
510
535
            bulk_update_row can execute the updates including the one
511
536
            defined in the bulk_update_row or not including the row
512
537
            in the call. This is up to the handler implementation and can
606
631
    }
607
632
    else
608
633
      table->file->unlock_row();
609
 
    session->row_count++;
 
634
    thd->row_count++;
610
635
  }
611
636
  dup_key_found= 0;
612
637
  /*
617
642
    It's assumed that if an error was set in combination with an effective
618
643
    killed status then the error is due to killing.
619
644
  */
620
 
  killed_status= session->killed; // get the status of the volatile
 
645
  killed_status= thd->killed; // get the status of the volatile
621
646
  // simulated killing after the loop must be ineffective for binlogging
622
 
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
 
647
  error= (killed_status == THD::NOT_KILLED)?  error : 1;
623
648
 
624
649
  if (error &&
625
650
      will_batch &&
646
671
  table->file->try_semi_consistent_read(0);
647
672
 
648
673
  if (!transactional_table && updated > 0)
649
 
    session->transaction.stmt.modified_non_trans_table= true;
 
674
    thd->transaction.stmt.modified_non_trans_table= true;
650
675
 
651
676
  end_read_record(&info);
652
677
  delete select;
653
 
  session->set_proc_info("end");
654
 
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
678
  thd_proc_info(thd, "end");
 
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
662
687
    Sometimes we want to binlog even if we updated no rows, in case user used
663
688
    it to be sure master and slave are in same state.
664
689
  */
665
 
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
 
690
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
666
691
  {
667
 
    if (session->transaction.stmt.modified_non_trans_table)
668
 
      session->transaction.all.modified_non_trans_table= true;
 
692
    if (mysql_bin_log.is_open())
 
693
    {
 
694
      if (error < 0)
 
695
        thd->clear_error();
 
696
      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
 
697
                            thd->query, thd->query_length,
 
698
                            transactional_table, false, killed_status) &&
 
699
          transactional_table)
 
700
      {
 
701
        error=1;                                // Rollback update
 
702
      }
 
703
    }
 
704
    if (thd->transaction.stmt.modified_non_trans_table)
 
705
      thd->transaction.all.modified_non_trans_table= true;
669
706
  }
670
 
  assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
671
 
  free_underlaid_joins(session, select_lex);
 
707
  assert(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
 
708
  free_underlaid_joins(thd, select_lex);
672
709
 
673
710
  /* If LAST_INSERT_ID(X) was used, report X */
674
 
  id= session->arg_of_last_insert_id_function ?
675
 
    session->first_successful_insert_id_in_prev_stmt : 0;
 
711
  id= thd->arg_of_last_insert_id_function ?
 
712
    thd->first_successful_insert_id_in_prev_stmt : 0;
676
713
 
677
 
  DRIZZLE_UPDATE_END();
 
714
  MYSQL_UPDATE_END();
678
715
  if (error < 0)
679
716
  {
680
717
    char buff[STRING_BUFFER_USUAL_SIZE];
681
718
    sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
682
 
            (ulong) session->cuted_fields);
683
 
    session->row_count_func=
684
 
      (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
685
 
    my_ok(session, (ulong) session->row_count_func, id, buff);
 
719
            (ulong) thd->cuted_fields);
 
720
    thd->row_count_func=
 
721
      (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
722
    my_ok(thd, (ulong) thd->row_count_func, id, buff);
686
723
  }
687
 
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              /* calc cuted fields */
688
 
  session->abort_on_warning= 0;
689
 
  return((error >= 0 || session->is_error()) ? 1 : 0);
 
724
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          /* calc cuted fields */
 
725
  thd->abort_on_warning= 0;
 
726
  return((error >= 0 || thd->is_error()) ? 1 : 0);
690
727
 
691
728
err:
692
729
  delete select;
693
 
  free_underlaid_joins(session, select_lex);
 
730
  free_underlaid_joins(thd, select_lex);
694
731
  if (table->key_read)
695
732
  {
696
733
    table->key_read=0;
697
734
    table->file->extra(HA_EXTRA_NO_KEYREAD);
698
735
  }
699
 
  session->abort_on_warning= 0;
 
736
  thd->abort_on_warning= 0;
700
737
 
701
738
abort:
702
 
  DRIZZLE_UPDATE_END();
 
739
  MYSQL_UPDATE_END();
703
740
  return(1);
704
741
}
705
742
 
708
745
 
709
746
  SYNOPSIS
710
747
    mysql_prepare_update()
711
 
    session                     - thread handler
 
748
    thd                 - thread handler
712
749
    table_list          - global/local table list
713
750
    conds               - conditions
714
 
    order_num           - number of order_st BY list entries
715
 
    order               - order_st BY clause list
 
751
    order_num           - number of ORDER BY list entries
 
752
    order               - ORDER BY clause list
716
753
 
717
754
  RETURN VALUE
718
755
    false OK
719
756
    true  error
720
757
*/
721
 
bool mysql_prepare_update(Session *session, TableList *table_list,
722
 
                         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)
723
760
{
 
761
  Item *fake_conds= 0;
724
762
  List<Item> all_fields;
725
 
  SELECT_LEX *select_lex= &session->lex->select_lex;
726
 
 
727
 
  session->lex->allow_sum_func= 0;
728
 
 
729
 
  if (setup_tables_and_check_access(session, &select_lex->context,
 
763
  SELECT_LEX *select_lex= &thd->lex->select_lex;
 
764
  
 
765
  /*
 
766
    Statement-based replication of UPDATE ... LIMIT is not safe as order of
 
767
    rows is not defined, so in mixed mode we go to row-based.
 
768
 
 
769
    Note that we may consider a statement as safe if ORDER BY primary_key
 
770
    is present. However it may confuse users to see very similiar statements
 
771
    replicated differently.
 
772
  */
 
773
  if (thd->lex->current_select->select_limit)
 
774
  {
 
775
    thd->lex->set_stmt_unsafe();
 
776
    thd->set_current_stmt_binlog_row_based_if_mixed();
 
777
  }
 
778
 
 
779
  thd->lex->allow_sum_func= 0;
 
780
 
 
781
  if (setup_tables_and_check_access(thd, &select_lex->context, 
730
782
                                    &select_lex->top_join_list,
731
783
                                    table_list,
732
784
                                    &select_lex->leaf_tables,
733
785
                                    false) ||
734
 
      setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
735
 
      select_lex->setup_ref_array(session, order_num) ||
736
 
      setup_order(session, select_lex->ref_pointer_array,
 
786
      setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
 
787
      select_lex->setup_ref_array(thd, order_num) ||
 
788
      setup_order(thd, select_lex->ref_pointer_array,
737
789
                  table_list, all_fields, all_fields, order))
738
790
    return(true);
739
791
 
740
792
  /* Check that we are not using table that we are updating in a sub select */
741
793
  {
742
 
    TableList *duplicate;
743
 
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
 
794
    TABLE_LIST *duplicate;
 
795
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
744
796
    {
745
797
      update_non_unique_table_error(table_list, "UPDATE", duplicate);
746
798
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
747
799
      return(true);
748
800
    }
749
801
  }
750
 
 
 
802
  select_lex->fix_prepare_information(thd, conds, &fake_conds);
751
803
  return(false);
752
804
}
753
805
 
754
806
 
755
807
/***************************************************************************
756
 
  Update multiple tables from join
 
808
  Update multiple tables from join 
757
809
***************************************************************************/
758
810
 
759
811
/*
766
818
  Item_field *item;
767
819
  table_map map= 0;
768
820
 
769
 
  while ((item= (Item_field *) item_it++))
 
821
  while ((item= (Item_field *) item_it++)) 
770
822
    map|= item->used_tables();
771
823
  return map;
772
824
}
777
829
 
778
830
  SYNOPSIS
779
831
    mysql_multi_update_prepare()
780
 
    session         thread handler
 
832
    thd         thread handler
781
833
 
782
834
  RETURN
783
835
    false OK
784
836
    true  Error
785
837
*/
786
838
 
787
 
int mysql_multi_update_prepare(Session *session)
 
839
int mysql_multi_update_prepare(THD *thd)
788
840
{
789
 
  LEX *lex= session->lex;
790
 
  TableList *table_list= lex->query_tables;
791
 
  TableList *tl, *leaves;
 
841
  LEX *lex= thd->lex;
 
842
  TABLE_LIST *table_list= lex->query_tables;
 
843
  TABLE_LIST *tl, *leaves;
792
844
  List<Item> *fields= &lex->select_lex.item_list;
793
845
  table_map tables_for_update;
794
846
  bool update_view= 0;
797
849
    counter else junk will be assigned here, but then replaced with real
798
850
    count in open_tables()
799
851
  */
800
 
  uint32_t  table_count= lex->table_count;
801
 
  const bool using_lock_tables= session->locked_tables != 0;
802
 
  bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
 
852
  uint  table_count= lex->table_count;
 
853
  const bool using_lock_tables= thd->locked_tables != 0;
 
854
  bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
803
855
  bool need_reopen= false;
804
 
 
 
856
  
805
857
 
806
858
  /* following need for prepared statements, to run next time multi-update */
807
 
  session->lex->sql_command= SQLCOM_UPDATE_MULTI;
 
859
  thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
808
860
 
809
861
reopen_tables:
810
862
 
811
863
  /* open tables and create derived ones, but do not lock and fill them */
812
864
  if (((original_multiupdate || need_reopen) &&
813
 
       open_tables(session, &table_list, &table_count, 0)) ||
 
865
       open_tables(thd, &table_list, &table_count, 0)) ||
814
866
      mysql_handle_derived(lex, &mysql_derived_prepare))
815
867
    return(true);
816
868
  /*
819
871
    call in setup_tables()).
820
872
  */
821
873
 
822
 
  if (setup_tables_and_check_access(session, &lex->select_lex.context,
 
874
  if (setup_tables_and_check_access(thd, &lex->select_lex.context,
823
875
                                    &lex->select_lex.top_join_list,
824
876
                                    table_list,
825
877
                                    &lex->select_lex.leaf_tables, false))
826
878
    return(true);
827
879
 
828
 
  if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
 
880
  if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
829
881
    return(true);
830
882
 
831
 
  if (update_view && check_fields(session, *fields))
 
883
  if (update_view && check_fields(thd, *fields))
832
884
  {
833
885
    return(true);
834
886
  }
841
893
  leaves= lex->select_lex.leaf_tables;
842
894
  for (tl= leaves; tl; tl= tl->next_leaf)
843
895
  {
844
 
    Table *table= tl->table;
 
896
    TABLE *table= tl->table;
845
897
    /* Only set timestamp column if this is not modified */
846
898
    if (table->timestamp_field &&
847
899
        bitmap_is_set(table->write_set,
864
916
        correct order of statements. Otherwise, we use a TL_READ lock to
865
917
        improve performance.
866
918
      */
867
 
      tl->lock_type= TL_READ;
 
919
      tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
868
920
      tl->updating= 0;
869
 
      /* Update Table::lock_type accordingly. */
 
921
      /* Update TABLE::lock_type accordingly. */
870
922
      if (!tl->placeholder() && !using_lock_tables)
871
923
        tl->table->reginfo.lock_type= tl->lock_type;
872
924
    }
873
925
  }
874
926
 
875
927
  /* now lock and fill tables */
876
 
  if (lock_tables(session, table_list, table_count, &need_reopen))
 
928
  if (lock_tables(thd, table_list, table_count, &need_reopen))
877
929
  {
878
930
    if (!need_reopen)
879
931
      return(true);
890
942
      item->cleanup();
891
943
 
892
944
    /* We have to cleanup translation tables of views. */
893
 
    for (TableList *tbl= table_list; tbl; tbl= tbl->next_global)
 
945
    for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
894
946
      tbl->cleanup_items();
895
947
 
896
 
    close_tables_for_reopen(session, &table_list);
 
948
    close_tables_for_reopen(thd, &table_list);
897
949
    goto reopen_tables;
898
950
  }
899
951
 
908
960
    if (tl->lock_type != TL_READ &&
909
961
        tl->lock_type != TL_READ_NO_INSERT)
910
962
    {
911
 
      TableList *duplicate;
912
 
      if ((duplicate= unique_table(session, tl, table_list, 0)))
 
963
      TABLE_LIST *duplicate;
 
964
      if ((duplicate= unique_table(thd, tl, table_list, 0)))
913
965
      {
914
966
        update_non_unique_table_error(table_list, "UPDATE", duplicate);
915
967
        return(true);
921
973
    further check in multi_update::prepare whether to use record cache.
922
974
  */
923
975
  lex->select_lex.exclude_from_table_unique_test= false;
924
 
 
925
 
  if (session->fill_derived_tables() &&
 
976
 
 
977
  if (thd->fill_derived_tables() &&
926
978
      mysql_handle_derived(lex, &mysql_derived_filling))
927
979
    return(true);
928
980
 
934
986
  Setup multi-update handling and call SELECT to do the join
935
987
*/
936
988
 
937
 
bool mysql_multi_update(Session *session,
938
 
                        TableList *table_list,
 
989
bool mysql_multi_update(THD *thd,
 
990
                        TABLE_LIST *table_list,
939
991
                        List<Item> *fields,
940
992
                        List<Item> *values,
941
993
                        COND *conds,
942
 
                        uint64_t options,
 
994
                        ulonglong options,
943
995
                        enum enum_duplicates handle_duplicates, bool ignore,
944
996
                        SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
945
997
{
946
998
  multi_update *result;
947
999
  bool res;
948
 
 
 
1000
  
949
1001
  if (!(result= new multi_update(table_list,
950
 
                                 session->lex->select_lex.leaf_tables,
 
1002
                                 thd->lex->select_lex.leaf_tables,
951
1003
                                 fields, values,
952
1004
                                 handle_duplicates, ignore)))
953
1005
    return(true);
954
1006
 
955
 
  session->abort_on_warning= true;
 
1007
  thd->abort_on_warning= test(thd->variables.sql_mode &
 
1008
                              (MODE_STRICT_TRANS_TABLES |
 
1009
                               MODE_STRICT_ALL_TABLES));
956
1010
 
957
1011
  List<Item> total_list;
958
 
  res= mysql_select(session, &select_lex->ref_pointer_array,
 
1012
  res= mysql_select(thd, &select_lex->ref_pointer_array,
959
1013
                      table_list, select_lex->with_wild,
960
1014
                      total_list,
961
 
                      conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
962
 
                      (order_st *)NULL,
 
1015
                      conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
 
1016
                      (ORDER *)NULL,
963
1017
                      options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
964
1018
                      OPTION_SETUP_TABLES_DONE,
965
1019
                      result, unit, select_lex);
966
 
  res|= session->is_error();
 
1020
  res|= thd->is_error();
967
1021
  if (unlikely(res))
968
1022
  {
969
1023
    /* If we had a another error reported earlier then this will be ignored */
971
1025
    result->abort();
972
1026
  }
973
1027
  delete result;
974
 
  session->abort_on_warning= 0;
 
1028
  thd->abort_on_warning= 0;
975
1029
  return(false);
976
1030
}
977
1031
 
978
1032
 
979
 
multi_update::multi_update(TableList *table_list,
980
 
                           TableList *leaves_list,
 
1033
multi_update::multi_update(TABLE_LIST *table_list,
 
1034
                           TABLE_LIST *leaves_list,
981
1035
                           List<Item> *field_list, List<Item> *value_list,
982
1036
                           enum enum_duplicates handle_duplicates_arg,
983
1037
                           bool ignore_arg)
993
1047
  Connect fields with tables and create list of tables that are updated
994
1048
*/
995
1049
 
996
 
int multi_update::prepare(List<Item> &,
997
 
                          SELECT_LEX_UNIT *)
 
1050
int multi_update::prepare(List<Item> &not_used_values __attribute__((__unused__)),
 
1051
                          SELECT_LEX_UNIT *lex_unit __attribute__((__unused__)))
998
1052
{
999
 
  TableList *table_ref;
 
1053
  TABLE_LIST *table_ref;
1000
1054
  SQL_LIST update;
1001
1055
  table_map tables_to_update;
1002
1056
  Item_field *item;
1003
1057
  List_iterator_fast<Item> field_it(*fields);
1004
1058
  List_iterator_fast<Item> value_it(*values);
1005
 
  uint32_t i, max_fields;
1006
 
  uint32_t leaf_table_count= 0;
1007
 
 
1008
 
  session->count_cuted_fields= CHECK_FIELD_WARN;
1009
 
  session->cuted_fields=0L;
1010
 
  session->set_proc_info("updating main table");
 
1059
  uint i, max_fields;
 
1060
  uint leaf_table_count= 0;
 
1061
  
 
1062
  thd->count_cuted_fields= CHECK_FIELD_WARN;
 
1063
  thd->cuted_fields=0L;
 
1064
  thd_proc_info(thd, "updating main table");
1011
1065
 
1012
1066
  tables_to_update= get_table_map(fields);
1013
1067
 
1022
1076
    reference tables
1023
1077
  */
1024
1078
 
1025
 
  if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
 
1079
  if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
1026
1080
    return(1);
1027
1081
 
1028
1082
  /*
1035
1089
  for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
1036
1090
  {
1037
1091
    /* TODO: add support of view of join support */
1038
 
    Table *table=table_ref->table;
 
1092
    TABLE *table=table_ref->table;
1039
1093
    leaf_table_count++;
1040
1094
    if (tables_to_update & table->map)
1041
1095
    {
1042
 
      TableList *tl= (TableList*) session->memdup((char*) table_ref,
 
1096
      TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
1043
1097
                                                sizeof(*tl));
1044
1098
      if (!tl)
1045
1099
        return(1);
1046
 
      update.link_in_list((unsigned char*) tl, (unsigned char**) &tl->next_local);
 
1100
      update.link_in_list((uchar*) tl, (uchar**) &tl->next_local);
1047
1101
      tl->shared= table_count++;
1048
1102
      table->no_keyread=1;
1049
1103
      table->covering_keys.clear_all();
1053
1107
 
1054
1108
 
1055
1109
  table_count=  update.elements;
1056
 
  update_tables= (TableList*) update.first;
 
1110
  update_tables= (TABLE_LIST*) update.first;
1057
1111
 
1058
 
  tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
1059
 
  tmp_table_param = (TMP_TABLE_PARAM*) session->calloc(sizeof(TMP_TABLE_PARAM) *
 
1112
  tmp_tables = (TABLE**) thd->calloc(sizeof(TABLE *) * table_count);
 
1113
  tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
1060
1114
                                                   table_count);
1061
 
  fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1062
 
                                              table_count);
1063
 
  values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
1064
 
                                              table_count);
1065
 
  if (session->is_fatal_error)
 
1115
  fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
 
1116
                                              table_count);
 
1117
  values_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
 
1118
                                              table_count);
 
1119
  if (thd->is_fatal_error)
1066
1120
    return(1);
1067
1121
  for (i=0 ; i < table_count ; i++)
1068
1122
  {
1069
1123
    fields_for_table[i]= new List_item;
1070
1124
    values_for_table[i]= new List_item;
1071
1125
  }
1072
 
  if (session->is_fatal_error)
 
1126
  if (thd->is_fatal_error)
1073
1127
    return(1);
1074
1128
 
1075
1129
  /* Split fields into fields_for_table[] and values_by_table[] */
1077
1131
  while ((item= (Item_field *) field_it++))
1078
1132
  {
1079
1133
    Item *value= value_it++;
1080
 
    uint32_t offset= item->field->table->pos_in_table_list->shared;
 
1134
    uint offset= item->field->table->pos_in_table_list->shared;
1081
1135
    fields_for_table[offset]->push_back(item);
1082
1136
    values_for_table[offset]->push_back(value);
1083
1137
  }
1084
 
  if (session->is_fatal_error)
 
1138
  if (thd->is_fatal_error)
1085
1139
    return(1);
1086
1140
 
1087
1141
  /* Allocate copy fields */
1089
1143
  for (i=0 ; i < table_count ; i++)
1090
1144
    set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
1091
1145
  copy_field= new Copy_field[max_fields];
1092
 
  return(session->is_fatal_error != 0);
 
1146
  return(thd->is_fatal_error != 0);
1093
1147
}
1094
1148
 
1095
1149
 
1098
1152
 
1099
1153
  SYNOPSIS
1100
1154
    safe_update_on_fly()
1101
 
    session                 Thread handler
 
1155
    thd                 Thread handler
1102
1156
    join_tab            How table is used in join
1103
1157
    all_tables          List of tables
1104
1158
 
1116
1170
    - Table is not joined to itself.
1117
1171
 
1118
1172
    This function gets information about fields to be updated from
1119
 
    the Table::write_set bitmap.
 
1173
    the TABLE::write_set bitmap.
1120
1174
 
1121
1175
  WARNING
1122
1176
    This code is a bit dependent of how make_join_readinfo() works.
1126
1180
    1           Safe to update
1127
1181
*/
1128
1182
 
1129
 
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
1130
 
                               TableList *table_ref, TableList *all_tables)
 
1183
static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
 
1184
                               TABLE_LIST *table_ref, TABLE_LIST *all_tables)
1131
1185
{
1132
 
  Table *table= join_tab->table;
1133
 
  if (unique_table(session, table_ref, all_tables, 0))
 
1186
  TABLE *table= join_tab->table;
 
1187
  if (unique_table(thd, table_ref, all_tables, 0))
1134
1188
    return 0;
1135
1189
  switch (join_tab->type) {
1136
1190
  case JT_SYSTEM:
1169
1223
bool
1170
1224
multi_update::initialize_tables(JOIN *join)
1171
1225
{
1172
 
  TableList *table_ref;
1173
 
 
1174
 
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
 
1226
  TABLE_LIST *table_ref;
 
1227
  
 
1228
  if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
1175
1229
    return(1);
1176
1230
  main_table=join->join_tab->table;
1177
1231
  table_to_update= 0;
1182
1236
  /* Create a temporary table for keys to all tables, except main table */
1183
1237
  for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
1184
1238
  {
1185
 
    Table *table=table_ref->table;
1186
 
    uint32_t cnt= table_ref->shared;
 
1239
    TABLE *table=table_ref->table;
 
1240
    uint cnt= table_ref->shared;
1187
1241
    List<Item> temp_fields;
1188
 
    order_st     group;
 
1242
    ORDER     group;
1189
1243
    TMP_TABLE_PARAM *tmp_param;
1190
1244
 
1191
1245
    table->mark_columns_needed_for_update();
1193
1247
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1194
1248
    if (table == main_table)                    // First table in join
1195
1249
    {
1196
 
      if (safe_update_on_fly(session, join->join_tab, table_ref, all_tables))
 
1250
      if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
1197
1251
      {
1198
1252
        table_to_update= main_table;            // Update table on the fly
1199
1253
        continue;
1211
1265
      OPTION condition.
1212
1266
    */
1213
1267
 
1214
 
    List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1215
 
    Table *tbl= table;
 
1268
    List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
 
1269
    TABLE *tbl= table;
1216
1270
    do
1217
1271
    {
1218
 
      Field_varstring *field= new Field_varstring(tbl->file->ref_length, 0,
1219
 
                                                  tbl->alias, tbl->s, &my_charset_bin);
 
1272
      Field_string *field= new Field_string(tbl->file->ref_length, 0,
 
1273
                                            tbl->alias, &my_charset_bin);
1220
1274
      if (!field)
1221
1275
        return(1);
1222
1276
      field->init(tbl);
1224
1278
        The field will be converted to varstring when creating tmp table if
1225
1279
        table to be updated was created by mysql 4.1. Deny this.
1226
1280
      */
 
1281
      field->can_alter_field_type= 0;
1227
1282
      Item_field *ifield= new Item_field((Field *) field);
1228
1283
      if (!ifield)
1229
1284
         return(1);
1235
1290
    temp_fields.concat(fields_for_table[cnt]);
1236
1291
 
1237
1292
    /* Make an unique key over the first field to avoid duplicated updates */
1238
 
    memset(&group, 0, sizeof(group));
 
1293
    bzero((char*) &group, sizeof(group));
1239
1294
    group.asc= 1;
1240
1295
    group.item= (Item**) temp_fields.head_ref();
1241
1296
 
1243
1298
    tmp_param->field_count=temp_fields.elements;
1244
1299
    tmp_param->group_parts=1;
1245
1300
    tmp_param->group_length= table->file->ref_length;
1246
 
    if (!(tmp_tables[cnt]=create_tmp_table(session,
 
1301
    if (!(tmp_tables[cnt]=create_tmp_table(thd,
1247
1302
                                           tmp_param,
1248
1303
                                           temp_fields,
1249
 
                                           (order_st*) &group, 0, 0,
 
1304
                                           (ORDER*) &group, 0, 0,
1250
1305
                                           TMP_TABLE_ALL_COLUMNS,
1251
1306
                                           HA_POS_ERROR,
1252
1307
                                           (char *) "")))
1259
1314
 
1260
1315
multi_update::~multi_update()
1261
1316
{
1262
 
  TableList *table;
 
1317
  TABLE_LIST *table;
1263
1318
  for (table= update_tables ; table; table= table->next_local)
1264
1319
  {
1265
1320
    table->table->no_keyread= table->table->no_cache= 0;
1269
1324
 
1270
1325
  if (tmp_tables)
1271
1326
  {
1272
 
    for (uint32_t cnt = 0; cnt < table_count; cnt++)
 
1327
    for (uint cnt = 0; cnt < table_count; cnt++)
1273
1328
    {
1274
1329
      if (tmp_tables[cnt])
1275
1330
      {
1276
 
        tmp_tables[cnt]->free_tmp_table(session);
 
1331
        free_tmp_table(thd, tmp_tables[cnt]);
1277
1332
        tmp_table_param[cnt].cleanup();
1278
1333
      }
1279
1334
    }
1280
1335
  }
1281
1336
  if (copy_field)
1282
1337
    delete [] copy_field;
1283
 
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              // Restore this setting
 
1338
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          // Restore this setting
1284
1339
  assert(trans_safe || !updated ||
1285
 
              session->transaction.all.modified_non_trans_table);
 
1340
              thd->transaction.all.modified_non_trans_table);
1286
1341
}
1287
1342
 
1288
1343
 
1289
 
bool multi_update::send_data(List<Item> &)
 
1344
bool multi_update::send_data(List<Item> &not_used_values __attribute__((__unused__)))
1290
1345
{
1291
 
  TableList *cur_table;
1292
 
 
 
1346
  TABLE_LIST *cur_table;
 
1347
  
1293
1348
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1294
1349
  {
1295
 
    Table *table= cur_table->table;
1296
 
    uint32_t offset= cur_table->shared;
 
1350
    TABLE *table= cur_table->table;
 
1351
    uint offset= cur_table->shared;
1297
1352
    /*
1298
1353
      Check if we are using outer join and we didn't find the row
1299
1354
      or if we have already updated this row in the previous call to this
1323
1378
                                            table->read_set));
1324
1379
      table->status|= STATUS_UPDATED;
1325
1380
      store_record(table,record[1]);
1326
 
      if (fill_record(session, *fields_for_table[offset],
 
1381
      if (fill_record(thd, *fields_for_table[offset],
1327
1382
                      *values_for_table[offset], 0))
1328
1383
        return(1);
1329
1384
 
1330
1385
      found++;
1331
 
      if (!can_compare_record || table->compare_record())
 
1386
      if (!can_compare_record || compare_record(table))
1332
1387
      {
1333
1388
        int error;
1334
1389
        if (!updated++)
1376
1431
          else
1377
1432
          {
1378
1433
            trans_safe= 0;
1379
 
            session->transaction.stmt.modified_non_trans_table= true;
 
1434
            thd->transaction.stmt.modified_non_trans_table= true;
1380
1435
          }
1381
1436
        }
1382
1437
      }
1384
1439
    else
1385
1440
    {
1386
1441
      int error;
1387
 
      Table *tmp_table= tmp_tables[offset];
 
1442
      TABLE *tmp_table= tmp_tables[offset];
1388
1443
      /*
1389
1444
       For updatable VIEW store rowid of the updated table and
1390
1445
       rowids of tables used in the CHECK OPTION condition.
1391
1446
      */
1392
 
      uint32_t field_num= 0;
1393
 
      List_iterator_fast<Table> tbl_it(unupdated_check_opt_tables);
1394
 
      Table *tbl= table;
 
1447
      uint field_num= 0;
 
1448
      List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
 
1449
      TABLE *tbl= table;
1395
1450
      do
1396
1451
      {
1397
1452
        tbl->file->position(tbl->record[0]);
1398
 
        Field_varstring *ref_field=
1399
 
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1400
 
        ref_field->store((char *)tbl->file->ref, tbl->file->ref_length,
1401
 
                         &my_charset_bin);
 
1453
        memcpy((char*) tmp_table->field[field_num]->ptr,
 
1454
               (char*) tbl->file->ref, tbl->file->ref_length);
1402
1455
        field_num++;
1403
1456
      } while ((tbl= tbl_it++));
1404
1457
 
1405
1458
      /* Store regular updated fields in the row. */
1406
 
      fill_record(session,
 
1459
      fill_record(thd,
1407
1460
                  tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1408
1461
                  *values_for_table[offset], 1);
1409
1462
 
1412
1465
      if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
1413
1466
      {
1414
1467
        if (error &&
1415
 
            create_myisam_from_heap(session, tmp_table,
 
1468
            create_myisam_from_heap(thd, tmp_table,
1416
1469
                                         tmp_table_param[offset].start_recinfo,
1417
1470
                                         &tmp_table_param[offset].recinfo,
1418
1471
                                         error, 1))
1428
1481
}
1429
1482
 
1430
1483
 
1431
 
void multi_update::send_error(uint32_t errcode,const char *err)
 
1484
void multi_update::send_error(uint errcode,const char *err)
1432
1485
{
1433
1486
  /* First send error what ever it is ... */
1434
1487
  my_error(errcode, MYF(0), err);
1439
1492
{
1440
1493
  /* the error was handled or nothing deleted and no side effects return */
1441
1494
  if (error_handled ||
1442
 
      (!session->transaction.stmt.modified_non_trans_table && !updated))
 
1495
      (!thd->transaction.stmt.modified_non_trans_table && !updated))
1443
1496
    return;
1444
1497
  /*
1445
1498
    If all tables that has been updated are trans safe then just do rollback.
1448
1501
 
1449
1502
  if (! trans_safe)
1450
1503
  {
1451
 
    assert(session->transaction.stmt.modified_non_trans_table);
 
1504
    assert(thd->transaction.stmt.modified_non_trans_table);
1452
1505
    if (do_update && table_count > 1)
1453
1506
    {
1454
1507
      /* Add warning here */
1455
 
      /*
 
1508
      /* 
1456
1509
         todo/fixme: do_update() is never called with the arg 1.
1457
1510
         should it change the signature to become argless?
1458
1511
      */
1459
 
      do_updates();
 
1512
      VOID(do_updates());
1460
1513
    }
1461
1514
  }
1462
 
  if (session->transaction.stmt.modified_non_trans_table)
 
1515
  if (thd->transaction.stmt.modified_non_trans_table)
1463
1516
  {
1464
 
    session->transaction.all.modified_non_trans_table= true;
 
1517
    /*
 
1518
      The query has to binlog because there's a modified non-transactional table
 
1519
      either from the query's list or via a stored routine: bug#13270,23333
 
1520
    */
 
1521
    if (mysql_bin_log.is_open())
 
1522
    {
 
1523
      /*
 
1524
        THD::killed status might not have been set ON at time of an error
 
1525
        got caught and if happens later the killed error is written
 
1526
        into repl event.
 
1527
      */
 
1528
      thd->binlog_query(THD::ROW_QUERY_TYPE,
 
1529
                        thd->query, thd->query_length,
 
1530
                        transactional_tables, false);
 
1531
    }
 
1532
    thd->transaction.all.modified_non_trans_table= true;
1465
1533
  }
1466
 
  assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
 
1534
  assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
1467
1535
}
1468
1536
 
1469
1537
 
1470
1538
int multi_update::do_updates()
1471
1539
{
1472
 
  TableList *cur_table;
 
1540
  TABLE_LIST *cur_table;
1473
1541
  int local_error= 0;
1474
1542
  ha_rows org_updated;
1475
 
  Table *table, *tmp_table;
1476
 
  List_iterator_fast<Table> check_opt_it(unupdated_check_opt_tables);
1477
 
 
 
1543
  TABLE *table, *tmp_table;
 
1544
  List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
 
1545
  
1478
1546
  do_update= 0;                                 // Don't retry this function
1479
1547
  if (!found)
1480
1548
    return(0);
1481
1549
  for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
1482
1550
  {
1483
1551
    bool can_compare_record;
1484
 
    uint32_t offset= cur_table->shared;
 
1552
    uint offset= cur_table->shared;
1485
1553
 
1486
1554
    table = cur_table->table;
1487
1555
    if (table == table_to_update)
1493
1561
    table->file->extra(HA_EXTRA_NO_CACHE);
1494
1562
 
1495
1563
    check_opt_it.rewind();
1496
 
    while(Table *tbl= check_opt_it++)
 
1564
    while(TABLE *tbl= check_opt_it++)
1497
1565
    {
1498
1566
      if (tbl->file->ha_rnd_init(1))
1499
1567
        goto err;
1504
1572
      Setup copy functions to copy fields from temporary table
1505
1573
    */
1506
1574
    List_iterator_fast<Item> field_it(*fields_for_table[offset]);
1507
 
    Field **field= tmp_table->field +
 
1575
    Field **field= tmp_table->field + 
1508
1576
                   1 + unupdated_check_opt_tables.elements; // Skip row pointers
1509
1577
    Copy_field *copy_field_ptr= copy_field, *copy_field_end;
1510
1578
    for ( ; *field ; field++)
1524
1592
 
1525
1593
    for (;;)
1526
1594
    {
1527
 
      if (session->killed && trans_safe)
 
1595
      if (thd->killed && trans_safe)
1528
1596
        goto err;
1529
1597
      if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
1530
1598
      {
1537
1605
 
1538
1606
      /* call rnd_pos() using rowids from temporary table */
1539
1607
      check_opt_it.rewind();
1540
 
      Table *tbl= table;
1541
 
      uint32_t field_num= 0;
 
1608
      TABLE *tbl= table;
 
1609
      uint field_num= 0;
1542
1610
      do
1543
1611
      {
1544
 
        Field_varstring *ref_field=
1545
 
          reinterpret_cast<Field_varstring *>(tmp_table->field[field_num]);
1546
1612
        if((local_error=
1547
1613
              tbl->file->rnd_pos(tbl->record[0],
1548
 
                                (unsigned char *) ref_field->ptr
1549
 
                                 + ref_field->length_bytes)))
 
1614
                                (uchar *) tmp_table->field[field_num]->ptr)))
1550
1615
          goto err;
1551
1616
        field_num++;
1552
1617
      } while((tbl= check_opt_it++));
1560
1625
           copy_field_ptr++)
1561
1626
        (*copy_field_ptr->do_copy)(copy_field_ptr);
1562
1627
 
1563
 
      if (!can_compare_record || table->compare_record())
 
1628
      if (!can_compare_record || compare_record(table))
1564
1629
      {
1565
1630
        if ((local_error=table->file->ha_update_row(table->record[1],
1566
1631
                                                    table->record[0])) &&
1584
1649
      else
1585
1650
      {
1586
1651
        trans_safe= 0;                          // Can't do safe rollback
1587
 
        session->transaction.stmt.modified_non_trans_table= true;
 
1652
        thd->transaction.stmt.modified_non_trans_table= true;
1588
1653
      }
1589
1654
    }
1590
1655
    (void) table->file->ha_rnd_end();
1591
1656
    (void) tmp_table->file->ha_rnd_end();
1592
1657
    check_opt_it.rewind();
1593
 
    while (Table *tbl= check_opt_it++)
 
1658
    while (TABLE *tbl= check_opt_it++)
1594
1659
        tbl->file->ha_rnd_end();
1595
1660
 
1596
1661
  }
1605
1670
  (void) table->file->ha_rnd_end();
1606
1671
  (void) tmp_table->file->ha_rnd_end();
1607
1672
  check_opt_it.rewind();
1608
 
  while (Table *tbl= check_opt_it++)
 
1673
  while (TABLE *tbl= check_opt_it++)
1609
1674
      tbl->file->ha_rnd_end();
1610
1675
 
1611
1676
  if (updated != org_updated)
1615
1680
    else
1616
1681
    {
1617
1682
      trans_safe= 0;
1618
 
      session->transaction.stmt.modified_non_trans_table= true;
 
1683
      thd->transaction.stmt.modified_non_trans_table= true;
1619
1684
    }
1620
1685
  }
1621
1686
  return(1);
1627
1692
bool multi_update::send_eof()
1628
1693
{
1629
1694
  char buff[STRING_BUFFER_USUAL_SIZE];
1630
 
  uint64_t id;
1631
 
  Session::killed_state killed_status= Session::NOT_KILLED;
1632
 
 
1633
 
  session->set_proc_info("updating reference tables");
1634
 
 
1635
 
  /*
 
1695
  ulonglong id;
 
1696
  THD::killed_state killed_status= THD::NOT_KILLED;
 
1697
  
 
1698
  thd_proc_info(thd, "updating reference tables");
 
1699
 
 
1700
  /* 
1636
1701
     Does updates for the last n - 1 tables, returns 0 if ok;
1637
1702
     error takes into account killed status gained in do_updates()
1638
1703
  */
1641
1706
    if local_error is not set ON until after do_updates() then
1642
1707
    later carried out killing should not affect binlogging.
1643
1708
  */
1644
 
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
1645
 
  session->set_proc_info("end");
 
1709
  killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
 
1710
  thd_proc_info(thd, "end");
1646
1711
 
1647
1712
  /*
1648
1713
    Write the SQL statement to the binlog if we updated
1649
1714
    rows and we succeeded or if we updated some non
1650
1715
    transactional tables.
1651
 
 
 
1716
    
1652
1717
    The query has to binlog because there's a modified non-transactional table
1653
1718
    either from the query's list or via a stored routine: bug#13270,23333
1654
1719
  */
1655
1720
 
1656
 
  assert(trans_safe || !updated ||
1657
 
              session->transaction.stmt.modified_non_trans_table);
1658
 
  if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
 
1721
  assert(trans_safe || !updated || 
 
1722
              thd->transaction.stmt.modified_non_trans_table);
 
1723
  if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
1659
1724
  {
1660
 
    if (session->transaction.stmt.modified_non_trans_table)
1661
 
      session->transaction.all.modified_non_trans_table= true;
 
1725
    if (mysql_bin_log.is_open())
 
1726
    {
 
1727
      if (local_error == 0)
 
1728
        thd->clear_error();
 
1729
      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
 
1730
                            thd->query, thd->query_length,
 
1731
                            transactional_tables, false, killed_status) &&
 
1732
          trans_safe)
 
1733
      {
 
1734
        local_error= 1;                         // Rollback update
 
1735
      }
 
1736
    }
 
1737
    if (thd->transaction.stmt.modified_non_trans_table)
 
1738
      thd->transaction.all.modified_non_trans_table= true;
1662
1739
  }
1663
1740
  if (local_error != 0)
1664
1741
    error_handled= true; // to force early leave from ::send_error()
1671
1748
    return(true);
1672
1749
  }
1673
1750
 
1674
 
  id= session->arg_of_last_insert_id_function ?
1675
 
    session->first_successful_insert_id_in_prev_stmt : 0;
 
1751
  id= thd->arg_of_last_insert_id_function ?
 
1752
    thd->first_successful_insert_id_in_prev_stmt : 0;
1676
1753
  sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
1677
 
          (ulong) session->cuted_fields);
1678
 
  session->row_count_func=
1679
 
    (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1680
 
  ::my_ok(session, (ulong) session->row_count_func, id, buff);
 
1754
          (ulong) thd->cuted_fields);
 
1755
  thd->row_count_func=
 
1756
    (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
1757
  ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
1681
1758
  return(false);
1682
1759
}