~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Paul McCullagh
  • Date: 2010-09-16 15:26:41 UTC
  • mto: (1771.3.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 1785.
  • Revision ID: paul.mccullagh@primebase.org-20100916152641-9mwb1hga0qwz41nu
Merged with 1.1 trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Insert of records */
18
18
 
19
 
#include <config.h>
 
19
#include "config.h"
20
20
#include <cstdio>
21
21
#include <drizzled/sql_select.h>
22
22
#include <drizzled/show.h>
25
25
#include <drizzled/probes.h>
26
26
#include <drizzled/sql_base.h>
27
27
#include <drizzled/sql_load.h>
28
 
#include <drizzled/field/epoch.h>
 
28
#include <drizzled/field/timestamp.h>
29
29
#include <drizzled/lock.h>
30
 
#include <drizzled/sql_table.h>
31
 
#include <drizzled/pthread_globals.h>
32
 
#include <drizzled/transaction_services.h>
33
 
#include <drizzled/plugin/transactional_storage_engine.h>
34
 
#include <drizzled/select_insert.h>
35
 
#include <drizzled/select_create.h>
36
 
 
37
 
#include <drizzled/table/shell.h>
 
30
#include "drizzled/sql_table.h"
 
31
#include "drizzled/pthread_globals.h"
 
32
#include "drizzled/transaction_services.h"
 
33
#include "drizzled/plugin/transactional_storage_engine.h"
38
34
 
39
35
namespace drizzled
40
36
{
87
83
  }
88
84
  else
89
85
  {                                             // Part field list
90
 
    Select_Lex *select_lex= &session->getLex()->select_lex;
 
86
    Select_Lex *select_lex= &session->lex->select_lex;
91
87
    Name_resolution_context *context= &select_lex->context;
92
88
    Name_resolution_context_state ctx_state;
93
89
    int res;
131
127
      }
132
128
      else
133
129
      {
134
 
        table->setWriteSet(table->timestamp_field->position());
 
130
        table->setWriteSet(table->timestamp_field->field_index);
135
131
      }
136
132
    }
137
133
  }
172
168
      Unmark the timestamp field so that we can check if this is modified
173
169
      by update_fields
174
170
    */
175
 
    timestamp_mark= table->write_set->test(table->timestamp_field->position());
176
 
    table->write_set->reset(table->timestamp_field->position());
 
171
    timestamp_mark= table->write_set->testAndClear(table->timestamp_field->field_index);
177
172
  }
178
173
 
179
174
  /* Check the fields we are going to modify */
191
186
 
192
187
    if (timestamp_mark)
193
188
    {
194
 
      table->setWriteSet(table->timestamp_field->position());
 
189
      table->setWriteSet(table->timestamp_field->field_index);
195
190
    }
196
191
  }
197
192
  return 0;
229
224
  end of dispatch_command().
230
225
*/
231
226
 
232
 
bool insert_query(Session *session,TableList *table_list,
 
227
bool mysql_insert(Session *session,TableList *table_list,
233
228
                  List<Item> &fields,
234
229
                  List<List_item> &values_list,
235
230
                  List<Item> &update_fields,
245
240
  uint64_t id;
246
241
  CopyInfo info;
247
242
  Table *table= 0;
248
 
  List<List_item>::iterator its(values_list.begin());
 
243
  List_iterator_fast<List_item> its(values_list);
249
244
  List_item *values;
250
245
  Name_resolution_context *context;
251
246
  Name_resolution_context_state ctx_state;
273
268
  values= its++;
274
269
  value_count= values->elements;
275
270
 
276
 
  if (prepare_insert(session, table_list, table, fields, values,
 
271
  if (mysql_prepare_insert(session, table_list, table, fields, values,
277
272
                           update_fields, update_values, duplic, &unused_conds,
278
273
                           false,
279
274
                           (fields.elements || !value_count ||
280
275
                            (0) != 0), !ignore))
281
 
  {
282
 
    if (table != NULL)
283
 
      table->cursor->ha_release_auto_increment();
284
 
    if (!joins_freed)
285
 
      free_underlaid_joins(session, &session->getLex()->select_lex);
286
 
    session->setAbortOnWarning(false);
287
 
    DRIZZLE_INSERT_DONE(1, 0);
288
 
    return true;
289
 
  }
 
276
    goto abort;
290
277
 
291
278
  /* mysql_prepare_insert set table_list->table if it was not set */
292
279
  table= table_list->table;
293
280
 
294
 
  context= &session->getLex()->select_lex.context;
 
281
  context= &session->lex->select_lex.context;
295
282
  /*
296
283
    These three asserts test the hypothesis that the resetting of the name
297
284
    resolution context below is not necessary at all since the list of local
317
304
    if (values->elements != value_count)
318
305
    {
319
306
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
320
 
 
321
 
      if (table != NULL)
322
 
        table->cursor->ha_release_auto_increment();
323
 
      if (!joins_freed)
324
 
        free_underlaid_joins(session, &session->getLex()->select_lex);
325
 
      session->setAbortOnWarning(false);
326
 
      DRIZZLE_INSERT_DONE(1, 0);
327
 
 
328
 
      return true;
 
307
      goto abort;
329
308
    }
330
309
    if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
331
 
    {
332
 
      if (table != NULL)
333
 
        table->cursor->ha_release_auto_increment();
334
 
      if (!joins_freed)
335
 
        free_underlaid_joins(session, &session->getLex()->select_lex);
336
 
      session->setAbortOnWarning(false);
337
 
      DRIZZLE_INSERT_DONE(1, 0);
338
 
      return true;
339
 
    }
 
310
      goto abort;
340
311
  }
341
 
  its= values_list.begin();
 
312
  its.rewind ();
342
313
 
343
314
  /* Restore the current context. */
344
315
  ctx_state.restore_state(context, table_list);
346
317
  /*
347
318
    Fill in the given fields and dump it to the table cursor
348
319
  */
 
320
  memset(&info, 0, sizeof(info));
349
321
  info.ignore= ignore;
350
322
  info.handle_duplicates=duplic;
351
323
  info.update_fields= &update_fields;
374
346
  }
375
347
 
376
348
 
377
 
  session->setAbortOnWarning(not ignore);
 
349
  session->abort_on_warning= !ignore;
378
350
 
379
351
  table->mark_columns_needed_for_insert();
380
352
 
424
396
    session->row_count++;
425
397
  }
426
398
 
427
 
  free_underlaid_joins(session, &session->getLex()->select_lex);
 
399
  free_underlaid_joins(session, &session->lex->select_lex);
428
400
  joins_freed= true;
429
401
 
430
402
  /*
480
452
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
481
453
 
482
454
  if (error)
483
 
  {
484
 
    if (table != NULL)
485
 
      table->cursor->ha_release_auto_increment();
486
 
    if (!joins_freed)
487
 
      free_underlaid_joins(session, &session->getLex()->select_lex);
488
 
    session->setAbortOnWarning(false);
489
 
    DRIZZLE_INSERT_DONE(1, 0);
490
 
    return true;
491
 
  }
492
 
 
 
455
    goto abort;
493
456
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
494
457
                                    !session->cuted_fields))
495
458
  {
496
459
    session->row_count_func= info.copied + info.deleted + info.updated;
497
 
    session->my_ok((ulong) session->rowCount(),
 
460
    session->my_ok((ulong) session->row_count_func,
498
461
                   info.copied + info.deleted + info.touched, id);
499
462
  }
500
463
  else
507
470
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
508
471
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
509
472
    session->row_count_func= info.copied + info.deleted + info.updated;
510
 
    session->my_ok((ulong) session->rowCount(),
 
473
    session->my_ok((ulong) session->row_count_func,
511
474
                   info.copied + info.deleted + info.touched, id, buff);
512
475
  }
513
 
  session->status_var.inserted_row_count+= session->rowCount();
514
 
  session->setAbortOnWarning(false);
515
 
  DRIZZLE_INSERT_DONE(0, session->rowCount());
516
 
 
 
476
  session->status_var.inserted_row_count+= session->row_count_func;
 
477
  session->abort_on_warning= 0;
 
478
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
517
479
  return false;
 
480
 
 
481
abort:
 
482
  if (table != NULL)
 
483
    table->cursor->ha_release_auto_increment();
 
484
  if (!joins_freed)
 
485
    free_underlaid_joins(session, &session->lex->select_lex);
 
486
  session->abort_on_warning= 0;
 
487
  DRIZZLE_INSERT_DONE(1, 0);
 
488
  return true;
518
489
}
519
490
 
520
491
 
522
493
  Check if table can be updated
523
494
 
524
495
  SYNOPSIS
525
 
     prepare_insert_check_table()
 
496
     mysql_prepare_insert_check_table()
526
497
     session            Thread handle
527
498
     table_list         Table list
528
499
     fields             List of fields to be updated
534
505
     true  ERROR
535
506
*/
536
507
 
537
 
static bool prepare_insert_check_table(Session *session, TableList *table_list,
 
508
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
538
509
                                             List<Item> &,
539
510
                                             bool select_insert)
540
511
{
547
518
     than INSERT.
548
519
  */
549
520
 
550
 
  if (setup_tables_and_check_access(session, &session->getLex()->select_lex.context,
551
 
                                    &session->getLex()->select_lex.top_join_list,
 
521
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
522
                                    &session->lex->select_lex.top_join_list,
552
523
                                    table_list,
553
 
                                    &session->getLex()->select_lex.leaf_tables,
 
524
                                    &session->lex->select_lex.leaf_tables,
554
525
                                    select_insert))
555
526
    return(true);
556
527
 
562
533
  Prepare items in INSERT statement
563
534
 
564
535
  SYNOPSIS
565
 
    prepare_insert()
 
536
    mysql_prepare_insert()
566
537
    session                     Thread handler
567
538
    table_list          Global/local table list
568
539
    table               Table to insert into (can be NULL if table should
589
560
    true  error
590
561
*/
591
562
 
592
 
bool prepare_insert(Session *session, TableList *table_list,
 
563
bool mysql_prepare_insert(Session *session, TableList *table_list,
593
564
                          Table *table, List<Item> &fields, List_item *values,
594
565
                          List<Item> &update_fields, List<Item> &update_values,
595
566
                          enum_duplicates duplic,
597
568
                          bool select_insert,
598
569
                          bool check_fields, bool abort_on_warning)
599
570
{
600
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
571
  Select_Lex *select_lex= &session->lex->select_lex;
601
572
  Name_resolution_context *context= &select_lex->context;
602
573
  Name_resolution_context_state ctx_state;
603
574
  bool insert_into_view= (0 != 0);
612
583
    inserting (for INSERT ... SELECT this is done by changing table_list,
613
584
    because INSERT ... SELECT share Select_Lex it with SELECT.
614
585
  */
615
 
  if (not select_insert)
 
586
  if (!select_insert)
616
587
  {
617
588
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
618
589
         un;
634
605
      return(true);
635
606
  }
636
607
 
637
 
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
 
608
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
638
609
    return(true);
639
610
 
640
611
 
660
631
 
661
632
    if (!res && check_fields)
662
633
    {
663
 
      bool saved_abort_on_warning= session->abortOnWarning();
664
 
 
665
 
      session->setAbortOnWarning(abort_on_warning);
 
634
      bool saved_abort_on_warning= session->abort_on_warning;
 
635
      session->abort_on_warning= abort_on_warning;
666
636
      res= check_that_all_fields_are_given_values(session,
667
637
                                                  table ? table :
668
638
                                                  context->table_list->table,
669
639
                                                  context->table_list);
670
 
      session->setAbortOnWarning(saved_abort_on_warning);
 
640
      session->abort_on_warning= saved_abort_on_warning;
671
641
    }
672
642
 
673
643
    if (!res && duplic == DUP_UPDATE)
678
648
    /* Restore the current context. */
679
649
    ctx_state.restore_state(context, table_list);
680
650
 
681
 
    if (not res)
 
651
    if (!res)
682
652
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
683
653
  }
684
654
 
685
655
  if (res)
686
656
    return(res);
687
657
 
688
 
  if (not table)
 
658
  if (!table)
689
659
    table= table_list->table;
690
660
 
691
 
  if (not select_insert)
 
661
  if (!select_insert)
692
662
  {
693
663
    TableList *duplicate;
694
664
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
698
668
      return true;
699
669
    }
700
670
  }
701
 
 
702
671
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
703
672
    table->prepare_for_position();
704
673
 
747
716
int write_record(Session *session, Table *table,CopyInfo *info)
748
717
{
749
718
  int error;
750
 
  std::vector<unsigned char> key;
751
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
 
719
  char *key=0;
 
720
  MyBitmap *save_read_set, *save_write_set;
752
721
  uint64_t prev_insert_id= table->cursor->next_insert_id;
753
722
  uint64_t insert_id_for_cur_row= 0;
754
723
 
818
787
          goto err;
819
788
        }
820
789
 
821
 
        if (not key.size())
 
790
        if (!key)
822
791
        {
823
 
          key.resize(table->getShare()->max_unique_length);
 
792
          if (!(key=(char*) malloc(table->getShare()->max_unique_length)))
 
793
          {
 
794
            error=ENOMEM;
 
795
            goto err;
 
796
          }
824
797
        }
825
 
        key_copy(&key[0], table->getInsertRecord(), table->key_info+key_nr, 0);
 
798
        key_copy((unsigned char*) key,table->getInsertRecord(),table->key_info+key_nr,0);
826
799
        if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
827
 
                                                    &key[0], HA_WHOLE_KEY,
 
800
                                                    (unsigned char*) key, HA_WHOLE_KEY,
828
801
                                                    HA_READ_KEY_EXACT))))
829
802
          goto err;
830
803
      }
850
823
          table->cursor->adjust_next_insert_id_after_explicit_value(
851
824
            table->next_number_field->val_int());
852
825
        info->touched++;
853
 
 
854
 
        if (! table->records_are_comparable() || table->compare_records())
 
826
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
827
             !bitmap_is_subset(table->write_set, table->read_set)) ||
 
828
            table->compare_record())
855
829
        {
856
830
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
857
831
                                                table->getInsertRecord())) &&
872
846
          /*
873
847
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
874
848
            like a regular UPDATE statement: it should not affect the value of a
875
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
849
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
876
850
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
877
851
            handled separately by Session::arg_of_last_insert_id_function.
878
852
          */
941
915
    */
942
916
    if (table->read_set != save_read_set ||
943
917
        table->write_set != save_write_set)
944
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
918
      table->column_bitmaps_set(save_read_set, save_write_set);
945
919
  }
946
920
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
947
921
  {
957
931
  session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
958
932
 
959
933
gok_or_after_err:
 
934
  if (key)
 
935
    free(key);
960
936
  if (!table->cursor->has_transactions())
961
937
    session->transaction.stmt.markModifiedNonTransData();
962
938
  return(0);
964
940
err:
965
941
  info->last_errno= error;
966
942
  /* current_select is NULL if this is a delayed insert */
967
 
  if (session->getLex()->current_select)
968
 
    session->getLex()->current_select->no_error= 0;        // Give error
 
943
  if (session->lex->current_select)
 
944
    session->lex->current_select->no_error= 0;        // Give error
969
945
  table->print_error(error,MYF(0));
970
946
 
971
947
before_err:
972
948
  table->cursor->restore_auto_increment(prev_insert_id);
973
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
974
 
  return 1;
 
949
  if (key)
 
950
    free(key);
 
951
  table->column_bitmaps_set(save_read_set, save_write_set);
 
952
  return(1);
975
953
}
976
954
 
977
955
 
1018
996
      }
1019
997
    }
1020
998
  }
1021
 
  return session->abortOnWarning() ? err : 0;
 
999
  return session->abort_on_warning ? err : 0;
1022
1000
}
1023
1001
 
1024
1002
/***************************************************************************
1030
1008
  make insert specific preparation and checks after opening tables
1031
1009
 
1032
1010
  SYNOPSIS
1033
 
    insert_select_prepare()
 
1011
    mysql_insert_select_prepare()
1034
1012
    session         thread handler
1035
1013
 
1036
1014
  RETURN
1038
1016
    true  Error
1039
1017
*/
1040
1018
 
1041
 
bool insert_select_prepare(Session *session)
 
1019
bool mysql_insert_select_prepare(Session *session)
1042
1020
{
1043
 
  LEX *lex= session->getLex();
 
1021
  LEX *lex= session->lex;
1044
1022
  Select_Lex *select_lex= &lex->select_lex;
1045
1023
 
1046
1024
  /*
1048
1026
    clause if table is VIEW
1049
1027
  */
1050
1028
 
1051
 
  if (prepare_insert(session, lex->query_tables,
 
1029
  if (mysql_prepare_insert(session, lex->query_tables,
1052
1030
                           lex->query_tables->table, lex->field_list, 0,
1053
1031
                           lex->update_list, lex->value_list,
1054
1032
                           lex->duplicates,
1072
1050
                             List<Item> *update_fields,
1073
1051
                             List<Item> *update_values,
1074
1052
                             enum_duplicates duplic,
1075
 
                             bool ignore_check_option_errors) :
1076
 
  table_list(table_list_par), table(table_par), fields(fields_par),
1077
 
  autoinc_value_of_last_inserted_row(0),
1078
 
  insert_into_view(table_list_par && 0 != 0)
 
1053
                             bool ignore_check_option_errors)
 
1054
  :table_list(table_list_par), table(table_par), fields(fields_par),
 
1055
   autoinc_value_of_last_inserted_row(0),
 
1056
   insert_into_view(table_list_par && 0 != 0)
1079
1057
{
 
1058
  memset(&info, 0, sizeof(info));
1080
1059
  info.handle_duplicates= duplic;
1081
1060
  info.ignore= ignore_check_option_errors;
1082
1061
  info.update_fields= update_fields;
1087
1066
int
1088
1067
select_insert::prepare(List<Item> &values, Select_Lex_Unit *u)
1089
1068
{
 
1069
  LEX *lex= session->lex;
1090
1070
  int res;
1091
1071
  table_map map= 0;
1092
 
  Select_Lex *lex_current_select_save= session->getLex()->current_select;
 
1072
  Select_Lex *lex_current_select_save= lex->current_select;
1093
1073
 
1094
1074
 
1095
1075
  unit= u;
1099
1079
    select, LEX::current_select should point to the first select while
1100
1080
    we are fixing fields from insert list.
1101
1081
  */
1102
 
  session->getLex()->current_select= &session->getLex()->select_lex;
 
1082
  lex->current_select= &lex->select_lex;
1103
1083
  res= check_insert_fields(session, table_list, *fields, values,
1104
1084
                           !insert_into_view, &map) ||
1105
1085
       setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0);
1106
1086
 
1107
1087
  if (!res && fields->elements)
1108
1088
  {
1109
 
    bool saved_abort_on_warning= session->abortOnWarning();
1110
 
    session->setAbortOnWarning(not info.ignore);
 
1089
    bool saved_abort_on_warning= session->abort_on_warning;
 
1090
    session->abort_on_warning= !info.ignore;
1111
1091
    res= check_that_all_fields_are_given_values(session, table_list->table,
1112
1092
                                                table_list);
1113
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1093
    session->abort_on_warning= saved_abort_on_warning;
1114
1094
  }
1115
1095
 
1116
1096
  if (info.handle_duplicates == DUP_UPDATE && !res)
1117
1097
  {
1118
 
    Name_resolution_context *context= &session->getLex()->select_lex.context;
 
1098
    Name_resolution_context *context= &lex->select_lex.context;
1119
1099
    Name_resolution_context_state ctx_state;
1120
1100
 
1121
1101
    /* Save the state of the current name resolution context. */
1133
1113
      We use next_name_resolution_table descructively, so check it first (views?)
1134
1114
    */
1135
1115
    assert (!table_list->next_name_resolution_table);
1136
 
    if (session->getLex()->select_lex.group_list.elements == 0 and
1137
 
        not session->getLex()->select_lex.with_sum_func)
 
1116
    if (lex->select_lex.group_list.elements == 0 &&
 
1117
        !lex->select_lex.with_sum_func)
1138
1118
      /*
1139
1119
        We must make a single context out of the two separate name resolution contexts :
1140
1120
        the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
1153
1133
        order to get correct values from those fields when the select
1154
1134
        employs a temporary table.
1155
1135
      */
1156
 
      List<Item>::iterator li(info.update_values->begin());
 
1136
      List_iterator<Item> li(*info.update_values);
1157
1137
      Item *item;
1158
1138
 
1159
1139
      while ((item= li++))
1160
1140
      {
1161
1141
        item->transform(&Item::update_value_transformer,
1162
 
                        (unsigned char*)session->getLex()->current_select);
 
1142
                        (unsigned char*)lex->current_select);
1163
1143
      }
1164
1144
    }
1165
1145
 
1167
1147
    ctx_state.restore_state(context, table_list);
1168
1148
  }
1169
1149
 
1170
 
  session->getLex()->current_select= lex_current_select_save;
 
1150
  lex->current_select= lex_current_select_save;
1171
1151
  if (res)
1172
1152
    return(1);
1173
1153
  /*
1183
1163
  if (unique_table(table_list, table_list->next_global))
1184
1164
  {
1185
1165
    /* Using same table for INSERT and SELECT */
1186
 
    session->getLex()->current_select->options|= OPTION_BUFFER_RESULT;
1187
 
    session->getLex()->current_select->join->select_options|= OPTION_BUFFER_RESULT;
 
1166
    lex->current_select->options|= OPTION_BUFFER_RESULT;
 
1167
    lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1188
1168
  }
1189
 
  else if (not (session->getLex()->current_select->options & OPTION_BUFFER_RESULT))
 
1169
  else if (!(lex->current_select->options & OPTION_BUFFER_RESULT))
1190
1170
  {
1191
1171
    /*
1192
1172
      We must not yet prepare the result table if it is the same as one of the
1203
1183
  table->next_number_field=table->found_next_number_field;
1204
1184
 
1205
1185
  session->cuted_fields=0;
1206
 
 
1207
1186
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1208
1187
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1209
 
 
1210
1188
  if (info.handle_duplicates == DUP_REPLACE)
1211
1189
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1212
 
 
1213
1190
  if (info.handle_duplicates == DUP_UPDATE)
1214
1191
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1215
 
 
1216
 
  session->setAbortOnWarning(not info.ignore);
 
1192
  session->abort_on_warning= !info.ignore;
1217
1193
  table->mark_columns_needed_for_insert();
1218
1194
 
1219
1195
 
1239
1215
 
1240
1216
int select_insert::prepare2(void)
1241
1217
{
1242
 
  if (session->getLex()->current_select->options & OPTION_BUFFER_RESULT)
 
1218
 
 
1219
  if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1243
1220
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
1244
 
 
1245
1221
  return(0);
1246
1222
}
1247
1223
 
1262
1238
    table->cursor->ha_reset();
1263
1239
  }
1264
1240
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1265
 
  session->setAbortOnWarning(false);
 
1241
  session->abort_on_warning= 0;
1266
1242
  return;
1267
1243
}
1268
1244
 
1270
1246
bool select_insert::send_data(List<Item> &values)
1271
1247
{
1272
1248
 
1273
 
  bool error= false;
 
1249
  bool error=0;
1274
1250
 
1275
1251
  if (unit->offset_limit_cnt)
1276
1252
  {                                             // using limit offset,count
1277
1253
    unit->offset_limit_cnt--;
1278
 
    return false;
 
1254
    return(0);
1279
1255
  }
1280
1256
 
1281
1257
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1282
1258
  store_values(values);
1283
1259
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1284
1260
  if (session->is_error())
1285
 
    return true;
 
1261
    return(1);
1286
1262
 
1287
1263
  // Release latches in case bulk insert takes a long time
1288
1264
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1332
1308
    fill_record(session, table->getFields(), values, true);
1333
1309
}
1334
1310
 
1335
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1311
void select_insert::send_error(uint32_t errcode,const char *err)
1336
1312
{
 
1313
 
 
1314
 
1337
1315
  my_message(errcode, err, MYF(0));
 
1316
 
 
1317
  return;
1338
1318
}
1339
1319
 
1340
1320
 
1383
1363
    (session->arg_of_last_insert_id_function ?
1384
1364
     session->first_successful_insert_id_in_prev_stmt :
1385
1365
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1386
 
  session->my_ok((ulong) session->rowCount(),
 
1366
  session->my_ok((ulong) session->row_count_func,
1387
1367
                 info.copied + info.deleted + info.touched, id, buff);
1388
 
  session->status_var.inserted_row_count+= session->rowCount(); 
1389
 
  DRIZZLE_INSERT_SELECT_DONE(0, session->rowCount());
 
1368
  session->status_var.inserted_row_count+= session->row_count_func; 
 
1369
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1390
1370
  return 0;
1391
1371
}
1392
1372
 
1488
1468
                                      List<Item> *items,
1489
1469
                                      bool is_if_not_exists,
1490
1470
                                      DrizzleLock **lock,
1491
 
                                      identifier::Table::const_reference identifier)
 
1471
                                      TableIdentifier &identifier)
1492
1472
{
 
1473
  Table tmp_table;              // Used during 'CreateField()'
1493
1474
  TableShare share(message::Table::INTERNAL);
 
1475
  Table *table= 0;
1494
1476
  uint32_t select_field_count= items->elements;
1495
1477
  /* Add selected items to field list */
1496
 
  List<Item>::iterator it(items->begin());
 
1478
  List_iterator_fast<Item> it(*items);
1497
1479
  Item *item;
1498
1480
  Field *tmp_field;
 
1481
  bool not_used;
1499
1482
 
1500
1483
  if (not (identifier.isTmp()) && create_table->table->db_stat)
1501
1484
  {
1505
1488
      create_info->table_existed= 1;            // Mark that table existed
1506
1489
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1507
1490
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1508
 
                          create_table->getTableName());
 
1491
                          create_table->table_name);
1509
1492
      return create_table->table;
1510
1493
    }
1511
1494
 
1512
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1495
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1513
1496
    return NULL;
1514
1497
  }
1515
1498
 
 
1499
  tmp_table.timestamp_field= 0;
 
1500
  tmp_table.setShare(&share);
 
1501
 
 
1502
  tmp_table.getMutableShare()->db_create_options= 0;
 
1503
  tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
 
1504
 
 
1505
  if (not table_proto.engine().name().compare("MyISAM"))
 
1506
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1507
  else if (not table_proto.engine().name().compare("MEMORY"))
 
1508
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1509
 
 
1510
  tmp_table.null_row= false;
 
1511
  tmp_table.maybe_null= false;
 
1512
 
 
1513
  while ((item=it++))
1516
1514
  {
1517
 
    table::Shell tmp_table(share);              // Used during 'CreateField()'
1518
 
 
1519
 
    if (not table_proto.engine().name().compare("MyISAM"))
1520
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1521
 
    else if (not table_proto.engine().name().compare("MEMORY"))
1522
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1523
 
 
1524
 
    tmp_table.in_use= session;
1525
 
 
1526
 
    while ((item=it++))
1527
 
    {
1528
 
      CreateField *cr_field;
1529
 
      Field *field, *def_field;
1530
 
      if (item->type() == Item::FUNC_ITEM)
1531
 
      {
1532
 
        if (item->result_type() != STRING_RESULT)
1533
 
        {
1534
 
          field= item->tmp_table_field(&tmp_table);
1535
 
        }
1536
 
        else
1537
 
        {
1538
 
          field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1539
 
        }
1540
 
      }
 
1515
    CreateField *cr_field;
 
1516
    Field *field, *def_field;
 
1517
    if (item->type() == Item::FUNC_ITEM)
 
1518
      if (item->result_type() != STRING_RESULT)
 
1519
        field= item->tmp_table_field(&tmp_table);
1541
1520
      else
1542
 
      {
1543
 
        field= create_tmp_field(session, &tmp_table, item, item->type(),
1544
 
                                (Item ***) 0, &tmp_field, &def_field, false,
1545
 
                                false, false, 0);
1546
 
      }
1547
 
 
1548
 
      if (!field ||
1549
 
          !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1550
 
                                            ((Item_field *)item)->field :
1551
 
                                            (Field*) 0))))
1552
 
      {
1553
 
        return NULL;
1554
 
      }
1555
 
 
1556
 
      if (item->maybe_null)
1557
 
      {
1558
 
        cr_field->flags &= ~NOT_NULL_FLAG;
1559
 
      }
1560
 
 
1561
 
      alter_info->create_list.push_back(cr_field);
1562
 
    }
 
1521
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1522
    else
 
1523
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1524
                              (Item ***) 0, &tmp_field, &def_field, false,
 
1525
                              false, false, 0);
 
1526
    if (!field ||
 
1527
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1528
                                           ((Item_field *)item)->field :
 
1529
                                           (Field*) 0))))
 
1530
      return NULL;
 
1531
    if (item->maybe_null)
 
1532
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1533
    alter_info->create_list.push_back(cr_field);
1563
1534
  }
1564
1535
 
1565
1536
  /*
1569
1540
    creating base table on which name we have exclusive lock. So code below
1570
1541
    should not cause deadlocks or races.
1571
1542
  */
1572
 
  Table *table= 0;
1573
1543
  {
1574
 
    if (not create_table_no_lock(session,
1575
 
                                 identifier,
1576
 
                                 create_info,
1577
 
                                 table_proto,
1578
 
                                 alter_info,
1579
 
                                 false,
1580
 
                                 select_field_count,
1581
 
                                 is_if_not_exists))
 
1544
    if (not mysql_create_table_no_lock(session,
 
1545
                                       identifier,
 
1546
                                       create_info,
 
1547
                                       table_proto,
 
1548
                                       alter_info,
 
1549
                                       false,
 
1550
                                       select_field_count,
 
1551
                                       is_if_not_exists))
1582
1552
    {
1583
1553
      if (create_info->table_existed && not identifier.isTmp())
1584
1554
      {
1587
1557
          or it was created via different mysqld front-end to the
1588
1558
          cluster. We don't have much options but throw an error.
1589
1559
        */
1590
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1560
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1591
1561
        return NULL;
1592
1562
      }
1593
1563
 
1594
1564
      if (not identifier.isTmp())
1595
1565
      {
1596
 
        /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1597
 
        boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1598
 
 
1599
 
        if (create_table->table)
 
1566
        LOCK_open.lock(); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1567
        if (session->reopen_name_locked_table(create_table, false))
1600
1568
        {
1601
 
          table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1602
 
 
1603
 
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1604
 
          {
1605
 
            (void)plugin::StorageEngine::dropTable(*session, identifier);
1606
 
          }
1607
 
          else
1608
 
          {
1609
 
            table= create_table->table;
1610
 
          }
 
1569
          quick_rm_table(*session, identifier);
1611
1570
        }
1612
1571
        else
1613
 
        {
1614
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
1615
 
        }
 
1572
          table= create_table->table;
 
1573
        LOCK_open.unlock();
1616
1574
      }
1617
1575
      else
1618
1576
      {
1625
1583
            it preparable for open. But let us do close_temporary_table() here
1626
1584
            just in case.
1627
1585
          */
1628
 
          session->drop_temporary_table(identifier);
 
1586
          session->drop_temporary_table(create_table);
1629
1587
        }
1630
1588
      }
1631
1589
    }
1632
 
    if (not table)                                   // open failed
 
1590
    if (!table)                                   // open failed
1633
1591
      return NULL;
1634
1592
  }
1635
1593
 
1636
1594
  table->reginfo.lock_type=TL_WRITE;
1637
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1595
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1596
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1638
1597
  {
1639
1598
    if (*lock)
1640
1599
    {
1641
 
      session->unlockTables(*lock);
 
1600
      mysql_unlock_tables(session, *lock);
1642
1601
      *lock= 0;
1643
1602
    }
1644
1603
 
1645
1604
    if (not create_info->table_existed)
1646
1605
      session->drop_open_table(table, identifier);
1647
 
 
1648
1606
    return NULL;
1649
1607
  }
1650
1608
 
1700
1658
 
1701
1659
  /* Mark all fields that are given values */
1702
1660
  for (Field **f= field ; *f ; f++)
1703
 
  {
1704
 
    table->setWriteSet((*f)->position());
1705
 
  }
 
1661
    table->setWriteSet((*f)->field_index);
1706
1662
 
1707
1663
  /* Don't set timestamp if used */
1708
1664
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1712
1668
  session->cuted_fields=0;
1713
1669
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1714
1670
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1715
 
 
1716
1671
  if (info.handle_duplicates == DUP_REPLACE)
1717
1672
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1718
 
 
1719
1673
  if (info.handle_duplicates == DUP_UPDATE)
1720
1674
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1721
 
 
1722
1675
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1723
 
  session->setAbortOnWarning(not info.ignore);
 
1676
  session->abort_on_warning= !info.ignore;
1724
1677
  if (check_that_all_fields_are_given_values(session, table, table_list))
1725
1678
    return(1);
1726
 
 
1727
1679
  table->mark_columns_needed_for_insert();
1728
1680
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1729
1681
  return(0);
1735
1687
}
1736
1688
 
1737
1689
 
1738
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1690
void select_create::send_error(uint32_t errcode,const char *err)
1739
1691
{
1740
1692
  /*
1741
1693
    This will execute any rollbacks that are necessary before writing
1749
1701
 
1750
1702
  */
1751
1703
  select_insert::send_error(errcode, err);
 
1704
 
 
1705
  return;
1752
1706
}
1753
1707
 
1754
1708
 
1767
1721
    if (!table->getShare()->getType())
1768
1722
    {
1769
1723
      TransactionServices &transaction_services= TransactionServices::singleton();
1770
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1724
      transaction_services.autocommitOrRollback(session, 0);
1771
1725
      (void) session->endActiveTransaction();
1772
1726
    }
1773
1727
 
1775
1729
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1776
1730
    if (m_plock)
1777
1731
    {
1778
 
      session->unlockTables(*m_plock);
 
1732
      mysql_unlock_tables(session, *m_plock);
1779
1733
      *m_plock= NULL;
1780
1734
      m_plock= NULL;
1781
1735
    }
1805
1759
 
1806
1760
  if (m_plock)
1807
1761
  {
1808
 
    session->unlockTables(*m_plock);
 
1762
    mysql_unlock_tables(session, *m_plock);
1809
1763
    *m_plock= NULL;
1810
1764
    m_plock= NULL;
1811
1765
  }