~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_update.cc

  • Committer: Patrick Galbraith
  • Date: 2008-07-24 16:57:40 UTC
  • mto: (202.2.4 rename-mysql-to-drizzle)
  • mto: This revision was merged to the branch mainline in revision 212.
  • Revision ID: patg@ishvara-20080724165740-x58yw6zs6d9o17lf
Most everything working with client rename
mysqlslap test still fails... can't connect to the server

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