~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_update.cc

  • Committer: Brian Aker
  • Date: 2008-10-20 04:28:21 UTC
  • mto: (492.3.21 drizzle-clean-code)
  • mto: This revision was merged to the branch mainline in revision 530.
  • Revision ID: brian@tangent.org-20081020042821-rqqdrccuu8195k3y
Second pass of thd cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
  SYNOPSIS
29
29
    check_fields()
30
 
    thd             thread handler
 
30
    session             thread handler
31
31
    items           Items for check
32
32
 
33
33
  RETURN
35
35
    false Items are OK
36
36
*/
37
37
 
38
 
static bool check_fields(Session *thd, List<Item> &items)
 
38
static bool check_fields(Session *session, List<Item> &items)
39
39
{
40
40
  List_iterator<Item> it(items);
41
41
  Item *item;
53
53
      we make temporary copy of Item_field, to avoid influence of changing
54
54
      result_field on Item_ref which refer on this field
55
55
    */
56
 
    thd->change_item_tree(it.ref(), new Item_field(thd, field));
 
56
    session->change_item_tree(it.ref(), new Item_field(session, field));
57
57
  }
58
58
  return false;
59
59
}
132
132
 
133
133
  SYNOPSIS
134
134
    mysql_update()
135
 
    thd                 thread handler
 
135
    session                     thread handler
136
136
    fields              fields for update
137
137
    values              values of fields for update
138
138
    conds               WHERE clause expression
148
148
    1  - error
149
149
*/
150
150
 
151
 
int mysql_update(Session *thd,
 
151
int mysql_update(Session *session,
152
152
                 TableList *table_list,
153
153
                 List<Item> &fields,
154
154
                 List<Item> &values,
159
159
                 bool ignore)
160
160
{
161
161
  bool          using_limit= limit != HA_POS_ERROR;
162
 
  bool          safe_update= test(thd->options & OPTION_SAFE_UPDATES);
 
162
  bool          safe_update= test(session->options & OPTION_SAFE_UPDATES);
163
163
  bool          used_key_is_modified, transactional_table, will_batch;
164
164
  bool          can_compare_record;
165
165
  int           error, loc_error;
171
171
  Table         *table;
172
172
  SQL_SELECT    *select;
173
173
  READ_RECORD   info;
174
 
  SELECT_LEX    *select_lex= &thd->lex->select_lex;
 
174
  SELECT_LEX    *select_lex= &session->lex->select_lex;
175
175
  bool          need_reopen;
176
176
  uint64_t     id;
177
177
  List<Item> all_fields;
179
179
  
180
180
  for ( ; ; )
181
181
  {
182
 
    if (open_tables(thd, &table_list, &table_count, 0))
 
182
    if (open_tables(session, &table_list, &table_count, 0))
183
183
      return(1);
184
184
 
185
 
    if (!lock_tables(thd, table_list, table_count, &need_reopen))
 
185
    if (!lock_tables(session, table_list, table_count, &need_reopen))
186
186
      break;
187
187
    if (!need_reopen)
188
188
      return(1);
189
 
    close_tables_for_reopen(thd, &table_list);
 
189
    close_tables_for_reopen(session, &table_list);
190
190
  }
191
191
 
192
 
  if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
193
 
      (thd->fill_derived_tables() &&
194
 
       mysql_handle_derived(thd->lex, &mysql_derived_filling)))
 
192
  if (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
 
193
      (session->fill_derived_tables() &&
 
194
       mysql_handle_derived(session->lex, &mysql_derived_filling)))
195
195
    return(1);
196
196
 
197
197
  DRIZZLE_UPDATE_START();
198
 
  thd->set_proc_info("init");
 
198
  session->set_proc_info("init");
199
199
  table= table_list->table;
200
200
 
201
201
  /* Calculate "table->covering_keys" based on the WHERE */
202
202
  table->covering_keys= table->s->keys_in_use;
203
203
  table->quick_keys.clear_all();
204
204
 
205
 
  if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
 
205
  if (mysql_prepare_update(session, table_list, &conds, order_num, order))
206
206
    goto abort;
207
207
 
208
208
  old_covering_keys= table->covering_keys;              // Keys used in WHERE
209
209
  /* Check the fields we are going to modify */
210
 
  if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
 
210
  if (setup_fields_with_no_wrap(session, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
211
211
    goto abort;                               /* purecov: inspected */
212
212
  if (table->timestamp_field)
213
213
  {
224
224
    }
225
225
  }
226
226
 
227
 
  if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
 
227
  if (setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0))
228
228
  {
229
 
    free_underlaid_joins(thd, select_lex);
 
229
    free_underlaid_joins(session, select_lex);
230
230
    goto abort;                               /* purecov: inspected */
231
231
  }
232
232
 
233
233
  if (select_lex->inner_refs_list.elements &&
234
 
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
 
234
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
235
235
  {
236
236
    DRIZZLE_UPDATE_END();
237
237
    return(-1);
240
240
  if (conds)
241
241
  {
242
242
    Item::cond_result cond_value;
243
 
    conds= remove_eq_conds(thd, conds, &cond_value);
 
243
    conds= remove_eq_conds(session, conds, &cond_value);
244
244
    if (cond_value == Item::COND_FALSE)
245
245
      limit= 0;                                   // Impossible WHERE
246
246
  }
263
263
 
264
264
  select= make_select(table, 0, 0, conds, 0, &error);
265
265
  if (error || !limit ||
266
 
      (select && select->check_quick(thd, safe_update, limit)))
 
266
      (select && select->check_quick(session, safe_update, limit)))
267
267
  {
268
268
    delete select;
269
 
    free_underlaid_joins(thd, select_lex);
 
269
    free_underlaid_joins(session, select_lex);
270
270
    if (error)
271
271
      goto abort;                               // Error in where
272
272
    DRIZZLE_UPDATE_END();
273
 
    my_ok(thd);                         // No matching records
 
273
    my_ok(session);                             // No matching records
274
274
    return(0);
275
275
  }
276
276
  if (!select && limit != HA_POS_ERROR)
281
281
  /* If running in safe sql mode, don't allow updates without keys */
282
282
  if (table->quick_keys.is_clear_all())
283
283
  {
284
 
    thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
284
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
285
285
    if (safe_update && !using_limit)
286
286
    {
287
287
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
341
341
      table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
342
342
                                                    MYF(MY_FAE | MY_ZEROFILL));
343
343
      if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
344
 
          (table->sort.found_records= filesort(thd, table, sortorder, length,
 
344
          (table->sort.found_records= filesort(session, table, sortorder, length,
345
345
                                               select, limit, 1,
346
346
                                               &examined_rows))
347
347
          == HA_POS_ERROR)
385
385
      */
386
386
 
387
387
      if (used_index == MAX_KEY || (select && select->quick))
388
 
        init_read_record(&info,thd,table,select,0,1);
 
388
        init_read_record(&info,session,table,select,0,1);
389
389
      else
390
 
        init_read_record_idx(&info, thd, table, 1, used_index);
 
390
        init_read_record_idx(&info, session, table, 1, used_index);
391
391
 
392
 
      thd->set_proc_info("Searching rows for update");
 
392
      session->set_proc_info("Searching rows for update");
393
393
      ha_rows tmp_limit= limit;
394
394
 
395
 
      while (!(error=info.read_record(&info)) && !thd->killed)
 
395
      while (!(error=info.read_record(&info)) && !session->killed)
396
396
      {
397
397
        if (!(select && select->skip_record()))
398
398
        {
415
415
        else
416
416
          table->file->unlock_row();
417
417
      }
418
 
      if (thd->killed && !error)
 
418
      if (session->killed && !error)
419
419
        error= 1;                               // Aborted
420
420
      limit= tmp_limit;
421
421
      table->file->try_semi_consistent_read(0);
451
451
  if (select && select->quick && select->quick->reset())
452
452
    goto err;
453
453
  table->file->try_semi_consistent_read(1);
454
 
  init_read_record(&info,thd,table,select,0,1);
 
454
  init_read_record(&info,session,table,select,0,1);
455
455
 
456
456
  updated= found= 0;
457
457
  /* Generate an error when trying to set a NOT NULL field to NULL. */
458
 
  thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
 
458
  session->count_cuted_fields= ignore ? CHECK_FIELD_WARN
459
459
                                  : CHECK_FIELD_ERROR_FOR_NULL;
460
 
  thd->cuted_fields=0L;
461
 
  thd->set_proc_info("Updating");
 
460
  session->cuted_fields=0L;
 
461
  session->set_proc_info("Updating");
462
462
 
463
463
  transactional_table= table->file->has_transactions();
464
 
  thd->abort_on_warning= test(!ignore);
 
464
  session->abort_on_warning= test(!ignore);
465
465
  will_batch= !table->file->start_bulk_update();
466
466
 
467
467
  /*
480
480
                         HA_PARTIAL_COLUMN_READ) ||
481
481
                       bitmap_is_subset(table->write_set, table->read_set));
482
482
 
483
 
  while (!(error=info.read_record(&info)) && !thd->killed)
 
483
  while (!(error=info.read_record(&info)) && !session->killed)
484
484
  {
485
485
    if (!(select && select->skip_record()))
486
486
    {
488
488
        continue;  /* repeat the read of the same row if it still exists */
489
489
 
490
490
      store_record(table,record[1]);
491
 
      if (fill_record(thd, fields, values, 0))
 
491
      if (fill_record(session, fields, values, 0))
492
492
        break; /* purecov: inspected */
493
493
 
494
494
      found++;
606
606
    }
607
607
    else
608
608
      table->file->unlock_row();
609
 
    thd->row_count++;
 
609
    session->row_count++;
610
610
  }
611
611
  dup_key_found= 0;
612
612
  /*
617
617
    It's assumed that if an error was set in combination with an effective
618
618
    killed status then the error is due to killing.
619
619
  */
620
 
  killed_status= thd->killed; // get the status of the volatile
 
620
  killed_status= session->killed; // get the status of the volatile
621
621
  // simulated killing after the loop must be ineffective for binlogging
622
622
  error= (killed_status == Session::NOT_KILLED)?  error : 1;
623
623
 
646
646
  table->file->try_semi_consistent_read(0);
647
647
 
648
648
  if (!transactional_table && updated > 0)
649
 
    thd->transaction.stmt.modified_non_trans_table= true;
 
649
    session->transaction.stmt.modified_non_trans_table= true;
650
650
 
651
651
  end_read_record(&info);
652
652
  delete select;
653
 
  thd->set_proc_info("end");
 
653
  session->set_proc_info("end");
654
654
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
655
655
 
656
656
  /*
662
662
    Sometimes we want to binlog even if we updated no rows, in case user used
663
663
    it to be sure master and slave are in same state.
664
664
  */
665
 
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
 
665
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
666
666
  {
667
667
    if (mysql_bin_log.is_open())
668
668
    {
669
669
      if (error < 0)
670
 
        thd->clear_error();
671
 
      if (thd->binlog_query(Session::ROW_QUERY_TYPE,
672
 
                            thd->query, thd->query_length,
 
670
        session->clear_error();
 
671
      if (session->binlog_query(Session::ROW_QUERY_TYPE,
 
672
                            session->query, session->query_length,
673
673
                            transactional_table, false, killed_status) &&
674
674
          transactional_table)
675
675
      {
676
676
        error=1;                                // Rollback update
677
677
      }
678
678
    }
679
 
    if (thd->transaction.stmt.modified_non_trans_table)
680
 
      thd->transaction.all.modified_non_trans_table= true;
 
679
    if (session->transaction.stmt.modified_non_trans_table)
 
680
      session->transaction.all.modified_non_trans_table= true;
681
681
  }
682
 
  assert(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
683
 
  free_underlaid_joins(thd, select_lex);
 
682
  assert(transactional_table || !updated || session->transaction.stmt.modified_non_trans_table);
 
683
  free_underlaid_joins(session, select_lex);
684
684
 
685
685
  /* If LAST_INSERT_ID(X) was used, report X */
686
 
  id= thd->arg_of_last_insert_id_function ?
687
 
    thd->first_successful_insert_id_in_prev_stmt : 0;
 
686
  id= session->arg_of_last_insert_id_function ?
 
687
    session->first_successful_insert_id_in_prev_stmt : 0;
688
688
 
689
689
  DRIZZLE_UPDATE_END();
690
690
  if (error < 0)
691
691
  {
692
692
    char buff[STRING_BUFFER_USUAL_SIZE];
693
693
    sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
694
 
            (ulong) thd->cuted_fields);
695
 
    thd->row_count_func=
696
 
      (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
697
 
    my_ok(thd, (ulong) thd->row_count_func, id, buff);
 
694
            (ulong) session->cuted_fields);
 
695
    session->row_count_func=
 
696
      (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
697
    my_ok(session, (ulong) session->row_count_func, id, buff);
698
698
  }
699
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          /* calc cuted fields */
700
 
  thd->abort_on_warning= 0;
701
 
  return((error >= 0 || thd->is_error()) ? 1 : 0);
 
699
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              /* calc cuted fields */
 
700
  session->abort_on_warning= 0;
 
701
  return((error >= 0 || session->is_error()) ? 1 : 0);
702
702
 
703
703
err:
704
704
  delete select;
705
 
  free_underlaid_joins(thd, select_lex);
 
705
  free_underlaid_joins(session, select_lex);
706
706
  if (table->key_read)
707
707
  {
708
708
    table->key_read=0;
709
709
    table->file->extra(HA_EXTRA_NO_KEYREAD);
710
710
  }
711
 
  thd->abort_on_warning= 0;
 
711
  session->abort_on_warning= 0;
712
712
 
713
713
abort:
714
714
  DRIZZLE_UPDATE_END();
720
720
 
721
721
  SYNOPSIS
722
722
    mysql_prepare_update()
723
 
    thd                 - thread handler
 
723
    session                     - thread handler
724
724
    table_list          - global/local table list
725
725
    conds               - conditions
726
726
    order_num           - number of order_st BY list entries
730
730
    false OK
731
731
    true  error
732
732
*/
733
 
bool mysql_prepare_update(Session *thd, TableList *table_list,
 
733
bool mysql_prepare_update(Session *session, TableList *table_list,
734
734
                         Item **conds, uint32_t order_num, order_st *order)
735
735
{
736
736
  List<Item> all_fields;
737
 
  SELECT_LEX *select_lex= &thd->lex->select_lex;
 
737
  SELECT_LEX *select_lex= &session->lex->select_lex;
738
738
  
739
739
  /*
740
740
    Statement-based replication of UPDATE ... LIMIT is not safe as order of
744
744
    is present. However it may confuse users to see very similiar statements
745
745
    replicated differently.
746
746
  */
747
 
  if (thd->lex->current_select->select_limit)
 
747
  if (session->lex->current_select->select_limit)
748
748
  {
749
 
    thd->lex->set_stmt_unsafe();
750
 
    thd->set_current_stmt_binlog_row_based_if_mixed();
 
749
    session->lex->set_stmt_unsafe();
 
750
    session->set_current_stmt_binlog_row_based_if_mixed();
751
751
  }
752
752
 
753
 
  thd->lex->allow_sum_func= 0;
 
753
  session->lex->allow_sum_func= 0;
754
754
 
755
 
  if (setup_tables_and_check_access(thd, &select_lex->context, 
 
755
  if (setup_tables_and_check_access(session, &select_lex->context, 
756
756
                                    &select_lex->top_join_list,
757
757
                                    table_list,
758
758
                                    &select_lex->leaf_tables,
759
759
                                    false) ||
760
 
      setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
761
 
      select_lex->setup_ref_array(thd, order_num) ||
762
 
      setup_order(thd, select_lex->ref_pointer_array,
 
760
      setup_conds(session, table_list, select_lex->leaf_tables, conds) ||
 
761
      select_lex->setup_ref_array(session, order_num) ||
 
762
      setup_order(session, select_lex->ref_pointer_array,
763
763
                  table_list, all_fields, all_fields, order))
764
764
    return(true);
765
765
 
766
766
  /* Check that we are not using table that we are updating in a sub select */
767
767
  {
768
768
    TableList *duplicate;
769
 
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
 
769
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
770
770
    {
771
771
      update_non_unique_table_error(table_list, "UPDATE", duplicate);
772
772
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
803
803
 
804
804
  SYNOPSIS
805
805
    mysql_multi_update_prepare()
806
 
    thd         thread handler
 
806
    session         thread handler
807
807
 
808
808
  RETURN
809
809
    false OK
810
810
    true  Error
811
811
*/
812
812
 
813
 
int mysql_multi_update_prepare(Session *thd)
 
813
int mysql_multi_update_prepare(Session *session)
814
814
{
815
 
  LEX *lex= thd->lex;
 
815
  LEX *lex= session->lex;
816
816
  TableList *table_list= lex->query_tables;
817
817
  TableList *tl, *leaves;
818
818
  List<Item> *fields= &lex->select_lex.item_list;
824
824
    count in open_tables()
825
825
  */
826
826
  uint32_t  table_count= lex->table_count;
827
 
  const bool using_lock_tables= thd->locked_tables != 0;
828
 
  bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
 
827
  const bool using_lock_tables= session->locked_tables != 0;
 
828
  bool original_multiupdate= (session->lex->sql_command == SQLCOM_UPDATE_MULTI);
829
829
  bool need_reopen= false;
830
830
  
831
831
 
832
832
  /* following need for prepared statements, to run next time multi-update */
833
 
  thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
 
833
  session->lex->sql_command= SQLCOM_UPDATE_MULTI;
834
834
 
835
835
reopen_tables:
836
836
 
837
837
  /* open tables and create derived ones, but do not lock and fill them */
838
838
  if (((original_multiupdate || need_reopen) &&
839
 
       open_tables(thd, &table_list, &table_count, 0)) ||
 
839
       open_tables(session, &table_list, &table_count, 0)) ||
840
840
      mysql_handle_derived(lex, &mysql_derived_prepare))
841
841
    return(true);
842
842
  /*
845
845
    call in setup_tables()).
846
846
  */
847
847
 
848
 
  if (setup_tables_and_check_access(thd, &lex->select_lex.context,
 
848
  if (setup_tables_and_check_access(session, &lex->select_lex.context,
849
849
                                    &lex->select_lex.top_join_list,
850
850
                                    table_list,
851
851
                                    &lex->select_lex.leaf_tables, false))
852
852
    return(true);
853
853
 
854
 
  if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
 
854
  if (setup_fields_with_no_wrap(session, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
855
855
    return(true);
856
856
 
857
 
  if (update_view && check_fields(thd, *fields))
 
857
  if (update_view && check_fields(session, *fields))
858
858
  {
859
859
    return(true);
860
860
  }
899
899
  }
900
900
 
901
901
  /* now lock and fill tables */
902
 
  if (lock_tables(thd, table_list, table_count, &need_reopen))
 
902
  if (lock_tables(session, table_list, table_count, &need_reopen))
903
903
  {
904
904
    if (!need_reopen)
905
905
      return(true);
919
919
    for (TableList *tbl= table_list; tbl; tbl= tbl->next_global)
920
920
      tbl->cleanup_items();
921
921
 
922
 
    close_tables_for_reopen(thd, &table_list);
 
922
    close_tables_for_reopen(session, &table_list);
923
923
    goto reopen_tables;
924
924
  }
925
925
 
935
935
        tl->lock_type != TL_READ_NO_INSERT)
936
936
    {
937
937
      TableList *duplicate;
938
 
      if ((duplicate= unique_table(thd, tl, table_list, 0)))
 
938
      if ((duplicate= unique_table(session, tl, table_list, 0)))
939
939
      {
940
940
        update_non_unique_table_error(table_list, "UPDATE", duplicate);
941
941
        return(true);
948
948
  */
949
949
  lex->select_lex.exclude_from_table_unique_test= false;
950
950
 
951
 
  if (thd->fill_derived_tables() &&
 
951
  if (session->fill_derived_tables() &&
952
952
      mysql_handle_derived(lex, &mysql_derived_filling))
953
953
    return(true);
954
954
 
960
960
  Setup multi-update handling and call SELECT to do the join
961
961
*/
962
962
 
963
 
bool mysql_multi_update(Session *thd,
 
963
bool mysql_multi_update(Session *session,
964
964
                        TableList *table_list,
965
965
                        List<Item> *fields,
966
966
                        List<Item> *values,
973
973
  bool res;
974
974
  
975
975
  if (!(result= new multi_update(table_list,
976
 
                                 thd->lex->select_lex.leaf_tables,
 
976
                                 session->lex->select_lex.leaf_tables,
977
977
                                 fields, values,
978
978
                                 handle_duplicates, ignore)))
979
979
    return(true);
980
980
 
981
 
  thd->abort_on_warning= true;
 
981
  session->abort_on_warning= true;
982
982
 
983
983
  List<Item> total_list;
984
 
  res= mysql_select(thd, &select_lex->ref_pointer_array,
 
984
  res= mysql_select(session, &select_lex->ref_pointer_array,
985
985
                      table_list, select_lex->with_wild,
986
986
                      total_list,
987
987
                      conds, 0, (order_st *) NULL, (order_st *)NULL, (Item *) NULL,
989
989
                      options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
990
990
                      OPTION_SETUP_TABLES_DONE,
991
991
                      result, unit, select_lex);
992
 
  res|= thd->is_error();
 
992
  res|= session->is_error();
993
993
  if (unlikely(res))
994
994
  {
995
995
    /* If we had a another error reported earlier then this will be ignored */
997
997
    result->abort();
998
998
  }
999
999
  delete result;
1000
 
  thd->abort_on_warning= 0;
 
1000
  session->abort_on_warning= 0;
1001
1001
  return(false);
1002
1002
}
1003
1003
 
1031
1031
  uint32_t i, max_fields;
1032
1032
  uint32_t leaf_table_count= 0;
1033
1033
  
1034
 
  thd->count_cuted_fields= CHECK_FIELD_WARN;
1035
 
  thd->cuted_fields=0L;
1036
 
  thd->set_proc_info("updating main table");
 
1034
  session->count_cuted_fields= CHECK_FIELD_WARN;
 
1035
  session->cuted_fields=0L;
 
1036
  session->set_proc_info("updating main table");
1037
1037
 
1038
1038
  tables_to_update= get_table_map(fields);
1039
1039
 
1048
1048
    reference tables
1049
1049
  */
1050
1050
 
1051
 
  if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
 
1051
  if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
1052
1052
    return(1);
1053
1053
 
1054
1054
  /*
1065
1065
    leaf_table_count++;
1066
1066
    if (tables_to_update & table->map)
1067
1067
    {
1068
 
      TableList *tl= (TableList*) thd->memdup((char*) table_ref,
 
1068
      TableList *tl= (TableList*) session->memdup((char*) table_ref,
1069
1069
                                                sizeof(*tl));
1070
1070
      if (!tl)
1071
1071
        return(1);
1081
1081
  table_count=  update.elements;
1082
1082
  update_tables= (TableList*) update.first;
1083
1083
 
1084
 
  tmp_tables = (Table**) thd->calloc(sizeof(Table *) * table_count);
1085
 
  tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
 
1084
  tmp_tables = (Table**) session->calloc(sizeof(Table *) * table_count);
 
1085
  tmp_table_param = (TMP_TABLE_PARAM*) session->calloc(sizeof(TMP_TABLE_PARAM) *
1086
1086
                                                   table_count);
1087
 
  fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1088
 
                                              table_count);
1089
 
  values_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
1090
 
                                              table_count);
1091
 
  if (thd->is_fatal_error)
 
1087
  fields_for_table= (List_item **) session->alloc(sizeof(List_item *) *
 
1088
                                              table_count);
 
1089
  values_for_table= (List_item **) session->alloc(sizeof(List_item *) *
 
1090
                                              table_count);
 
1091
  if (session->is_fatal_error)
1092
1092
    return(1);
1093
1093
  for (i=0 ; i < table_count ; i++)
1094
1094
  {
1095
1095
    fields_for_table[i]= new List_item;
1096
1096
    values_for_table[i]= new List_item;
1097
1097
  }
1098
 
  if (thd->is_fatal_error)
 
1098
  if (session->is_fatal_error)
1099
1099
    return(1);
1100
1100
 
1101
1101
  /* Split fields into fields_for_table[] and values_by_table[] */
1107
1107
    fields_for_table[offset]->push_back(item);
1108
1108
    values_for_table[offset]->push_back(value);
1109
1109
  }
1110
 
  if (thd->is_fatal_error)
 
1110
  if (session->is_fatal_error)
1111
1111
    return(1);
1112
1112
 
1113
1113
  /* Allocate copy fields */
1115
1115
  for (i=0 ; i < table_count ; i++)
1116
1116
    set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
1117
1117
  copy_field= new Copy_field[max_fields];
1118
 
  return(thd->is_fatal_error != 0);
 
1118
  return(session->is_fatal_error != 0);
1119
1119
}
1120
1120
 
1121
1121
 
1124
1124
 
1125
1125
  SYNOPSIS
1126
1126
    safe_update_on_fly()
1127
 
    thd                 Thread handler
 
1127
    session                 Thread handler
1128
1128
    join_tab            How table is used in join
1129
1129
    all_tables          List of tables
1130
1130
 
1152
1152
    1           Safe to update
1153
1153
*/
1154
1154
 
1155
 
static bool safe_update_on_fly(Session *thd, JOIN_TAB *join_tab,
 
1155
static bool safe_update_on_fly(Session *session, JOIN_TAB *join_tab,
1156
1156
                               TableList *table_ref, TableList *all_tables)
1157
1157
{
1158
1158
  Table *table= join_tab->table;
1159
 
  if (unique_table(thd, table_ref, all_tables, 0))
 
1159
  if (unique_table(session, table_ref, all_tables, 0))
1160
1160
    return 0;
1161
1161
  switch (join_tab->type) {
1162
1162
  case JT_SYSTEM:
1197
1197
{
1198
1198
  TableList *table_ref;
1199
1199
  
1200
 
  if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
 
1200
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
1201
1201
    return(1);
1202
1202
  main_table=join->join_tab->table;
1203
1203
  table_to_update= 0;
1219
1219
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1220
1220
    if (table == main_table)                    // First table in join
1221
1221
    {
1222
 
      if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
 
1222
      if (safe_update_on_fly(session, join->join_tab, table_ref, all_tables))
1223
1223
      {
1224
1224
        table_to_update= main_table;            // Update table on the fly
1225
1225
        continue;
1273
1273
    tmp_param->field_count=temp_fields.elements;
1274
1274
    tmp_param->group_parts=1;
1275
1275
    tmp_param->group_length= table->file->ref_length;
1276
 
    if (!(tmp_tables[cnt]=create_tmp_table(thd,
 
1276
    if (!(tmp_tables[cnt]=create_tmp_table(session,
1277
1277
                                           tmp_param,
1278
1278
                                           temp_fields,
1279
1279
                                           (order_st*) &group, 0, 0,
1303
1303
    {
1304
1304
      if (tmp_tables[cnt])
1305
1305
      {
1306
 
        tmp_tables[cnt]->free_tmp_table(thd);
 
1306
        tmp_tables[cnt]->free_tmp_table(session);
1307
1307
        tmp_table_param[cnt].cleanup();
1308
1308
      }
1309
1309
    }
1310
1310
  }
1311
1311
  if (copy_field)
1312
1312
    delete [] copy_field;
1313
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;          // Restore this setting
 
1313
  session->count_cuted_fields= CHECK_FIELD_IGNORE;              // Restore this setting
1314
1314
  assert(trans_safe || !updated ||
1315
 
              thd->transaction.all.modified_non_trans_table);
 
1315
              session->transaction.all.modified_non_trans_table);
1316
1316
}
1317
1317
 
1318
1318
 
1353
1353
                                            table->read_set));
1354
1354
      table->status|= STATUS_UPDATED;
1355
1355
      store_record(table,record[1]);
1356
 
      if (fill_record(thd, *fields_for_table[offset],
 
1356
      if (fill_record(session, *fields_for_table[offset],
1357
1357
                      *values_for_table[offset], 0))
1358
1358
        return(1);
1359
1359
 
1406
1406
          else
1407
1407
          {
1408
1408
            trans_safe= 0;
1409
 
            thd->transaction.stmt.modified_non_trans_table= true;
 
1409
            session->transaction.stmt.modified_non_trans_table= true;
1410
1410
          }
1411
1411
        }
1412
1412
      }
1431
1431
      } while ((tbl= tbl_it++));
1432
1432
 
1433
1433
      /* Store regular updated fields in the row. */
1434
 
      fill_record(thd,
 
1434
      fill_record(session,
1435
1435
                  tmp_table->field + 1 + unupdated_check_opt_tables.elements,
1436
1436
                  *values_for_table[offset], 1);
1437
1437
 
1440
1440
      if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
1441
1441
      {
1442
1442
        if (error &&
1443
 
            create_myisam_from_heap(thd, tmp_table,
 
1443
            create_myisam_from_heap(session, tmp_table,
1444
1444
                                         tmp_table_param[offset].start_recinfo,
1445
1445
                                         &tmp_table_param[offset].recinfo,
1446
1446
                                         error, 1))
1467
1467
{
1468
1468
  /* the error was handled or nothing deleted and no side effects return */
1469
1469
  if (error_handled ||
1470
 
      (!thd->transaction.stmt.modified_non_trans_table && !updated))
 
1470
      (!session->transaction.stmt.modified_non_trans_table && !updated))
1471
1471
    return;
1472
1472
  /*
1473
1473
    If all tables that has been updated are trans safe then just do rollback.
1476
1476
 
1477
1477
  if (! trans_safe)
1478
1478
  {
1479
 
    assert(thd->transaction.stmt.modified_non_trans_table);
 
1479
    assert(session->transaction.stmt.modified_non_trans_table);
1480
1480
    if (do_update && table_count > 1)
1481
1481
    {
1482
1482
      /* Add warning here */
1487
1487
      do_updates();
1488
1488
    }
1489
1489
  }
1490
 
  if (thd->transaction.stmt.modified_non_trans_table)
 
1490
  if (session->transaction.stmt.modified_non_trans_table)
1491
1491
  {
1492
1492
    /*
1493
1493
      The query has to binlog because there's a modified non-transactional table
1500
1500
        got caught and if happens later the killed error is written
1501
1501
        into repl event.
1502
1502
      */
1503
 
      thd->binlog_query(Session::ROW_QUERY_TYPE,
1504
 
                        thd->query, thd->query_length,
 
1503
      session->binlog_query(Session::ROW_QUERY_TYPE,
 
1504
                        session->query, session->query_length,
1505
1505
                        transactional_tables, false);
1506
1506
    }
1507
 
    thd->transaction.all.modified_non_trans_table= true;
 
1507
    session->transaction.all.modified_non_trans_table= true;
1508
1508
  }
1509
 
  assert(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
 
1509
  assert(trans_safe || !updated || session->transaction.stmt.modified_non_trans_table);
1510
1510
}
1511
1511
 
1512
1512
 
1567
1567
 
1568
1568
    for (;;)
1569
1569
    {
1570
 
      if (thd->killed && trans_safe)
 
1570
      if (session->killed && trans_safe)
1571
1571
        goto err;
1572
1572
      if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
1573
1573
      {
1624
1624
      else
1625
1625
      {
1626
1626
        trans_safe= 0;                          // Can't do safe rollback
1627
 
        thd->transaction.stmt.modified_non_trans_table= true;
 
1627
        session->transaction.stmt.modified_non_trans_table= true;
1628
1628
      }
1629
1629
    }
1630
1630
    (void) table->file->ha_rnd_end();
1655
1655
    else
1656
1656
    {
1657
1657
      trans_safe= 0;
1658
 
      thd->transaction.stmt.modified_non_trans_table= true;
 
1658
      session->transaction.stmt.modified_non_trans_table= true;
1659
1659
    }
1660
1660
  }
1661
1661
  return(1);
1670
1670
  uint64_t id;
1671
1671
  Session::killed_state killed_status= Session::NOT_KILLED;
1672
1672
  
1673
 
  thd->set_proc_info("updating reference tables");
 
1673
  session->set_proc_info("updating reference tables");
1674
1674
 
1675
1675
  /* 
1676
1676
     Does updates for the last n - 1 tables, returns 0 if ok;
1681
1681
    if local_error is not set ON until after do_updates() then
1682
1682
    later carried out killing should not affect binlogging.
1683
1683
  */
1684
 
  killed_status= (local_error == 0)? Session::NOT_KILLED : thd->killed;
1685
 
  thd->set_proc_info("end");
 
1684
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
 
1685
  session->set_proc_info("end");
1686
1686
 
1687
1687
  /*
1688
1688
    Write the SQL statement to the binlog if we updated
1694
1694
  */
1695
1695
 
1696
1696
  assert(trans_safe || !updated || 
1697
 
              thd->transaction.stmt.modified_non_trans_table);
1698
 
  if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
 
1697
              session->transaction.stmt.modified_non_trans_table);
 
1698
  if (local_error == 0 || session->transaction.stmt.modified_non_trans_table)
1699
1699
  {
1700
1700
    if (mysql_bin_log.is_open())
1701
1701
    {
1702
1702
      if (local_error == 0)
1703
 
        thd->clear_error();
1704
 
      if (thd->binlog_query(Session::ROW_QUERY_TYPE,
1705
 
                            thd->query, thd->query_length,
 
1703
        session->clear_error();
 
1704
      if (session->binlog_query(Session::ROW_QUERY_TYPE,
 
1705
                            session->query, session->query_length,
1706
1706
                            transactional_tables, false, killed_status) &&
1707
1707
          trans_safe)
1708
1708
      {
1709
1709
        local_error= 1;                         // Rollback update
1710
1710
      }
1711
1711
    }
1712
 
    if (thd->transaction.stmt.modified_non_trans_table)
1713
 
      thd->transaction.all.modified_non_trans_table= true;
 
1712
    if (session->transaction.stmt.modified_non_trans_table)
 
1713
      session->transaction.all.modified_non_trans_table= true;
1714
1714
  }
1715
1715
  if (local_error != 0)
1716
1716
    error_handled= true; // to force early leave from ::send_error()
1723
1723
    return(true);
1724
1724
  }
1725
1725
 
1726
 
  id= thd->arg_of_last_insert_id_function ?
1727
 
    thd->first_successful_insert_id_in_prev_stmt : 0;
 
1726
  id= session->arg_of_last_insert_id_function ?
 
1727
    session->first_successful_insert_id_in_prev_stmt : 0;
1728
1728
  sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated,
1729
 
          (ulong) thd->cuted_fields);
1730
 
  thd->row_count_func=
1731
 
    (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
1732
 
  ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
 
1729
          (ulong) session->cuted_fields);
 
1730
  session->row_count_func=
 
1731
    (session->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
 
1732
  ::my_ok(session, (ulong) session->row_count_func, id, buff);
1733
1733
  return(false);
1734
1734
}