~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Brian Aker
  • Date: 2010-10-06 18:16:00 UTC
  • mto: (1818.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1819.
  • Revision ID: brian@tangent.org-20101006181600-q7zuzw31zlq030ra
Convert sql_string to use size_t (this should clean up ICC warnings).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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);
374
345
  }
375
346
 
376
347
 
377
 
  session->setAbortOnWarning(not ignore);
 
348
  session->abort_on_warning= !ignore;
378
349
 
379
350
  table->mark_columns_needed_for_insert();
380
351
 
424
395
    session->row_count++;
425
396
  }
426
397
 
427
 
  free_underlaid_joins(session, &session->getLex()->select_lex);
 
398
  free_underlaid_joins(session, &session->lex->select_lex);
428
399
  joins_freed= true;
429
400
 
430
401
  /*
480
451
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
481
452
 
482
453
  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
 
 
 
454
    goto abort;
493
455
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
494
456
                                    !session->cuted_fields))
495
457
  {
496
458
    session->row_count_func= info.copied + info.deleted + info.updated;
497
 
    session->my_ok((ulong) session->rowCount(),
 
459
    session->my_ok((ulong) session->row_count_func,
498
460
                   info.copied + info.deleted + info.touched, id);
499
461
  }
500
462
  else
507
469
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
508
470
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
509
471
    session->row_count_func= info.copied + info.deleted + info.updated;
510
 
    session->my_ok((ulong) session->rowCount(),
 
472
    session->my_ok((ulong) session->row_count_func,
511
473
                   info.copied + info.deleted + info.touched, id, buff);
512
474
  }
513
 
  session->status_var.inserted_row_count+= session->rowCount();
514
 
  session->setAbortOnWarning(false);
515
 
  DRIZZLE_INSERT_DONE(0, session->rowCount());
516
 
 
 
475
  session->status_var.inserted_row_count+= session->row_count_func;
 
476
  session->abort_on_warning= 0;
 
477
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
517
478
  return false;
 
479
 
 
480
abort:
 
481
  if (table != NULL)
 
482
    table->cursor->ha_release_auto_increment();
 
483
  if (!joins_freed)
 
484
    free_underlaid_joins(session, &session->lex->select_lex);
 
485
  session->abort_on_warning= 0;
 
486
  DRIZZLE_INSERT_DONE(1, 0);
 
487
  return true;
518
488
}
519
489
 
520
490
 
522
492
  Check if table can be updated
523
493
 
524
494
  SYNOPSIS
525
 
     prepare_insert_check_table()
 
495
     mysql_prepare_insert_check_table()
526
496
     session            Thread handle
527
497
     table_list         Table list
528
498
     fields             List of fields to be updated
534
504
     true  ERROR
535
505
*/
536
506
 
537
 
static bool prepare_insert_check_table(Session *session, TableList *table_list,
 
507
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
538
508
                                             List<Item> &,
539
509
                                             bool select_insert)
540
510
{
547
517
     than INSERT.
548
518
  */
549
519
 
550
 
  if (setup_tables_and_check_access(session, &session->getLex()->select_lex.context,
551
 
                                    &session->getLex()->select_lex.top_join_list,
 
520
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
521
                                    &session->lex->select_lex.top_join_list,
552
522
                                    table_list,
553
 
                                    &session->getLex()->select_lex.leaf_tables,
 
523
                                    &session->lex->select_lex.leaf_tables,
554
524
                                    select_insert))
555
525
    return(true);
556
526
 
562
532
  Prepare items in INSERT statement
563
533
 
564
534
  SYNOPSIS
565
 
    prepare_insert()
 
535
    mysql_prepare_insert()
566
536
    session                     Thread handler
567
537
    table_list          Global/local table list
568
538
    table               Table to insert into (can be NULL if table should
589
559
    true  error
590
560
*/
591
561
 
592
 
bool prepare_insert(Session *session, TableList *table_list,
 
562
bool mysql_prepare_insert(Session *session, TableList *table_list,
593
563
                          Table *table, List<Item> &fields, List_item *values,
594
564
                          List<Item> &update_fields, List<Item> &update_values,
595
565
                          enum_duplicates duplic,
597
567
                          bool select_insert,
598
568
                          bool check_fields, bool abort_on_warning)
599
569
{
600
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
570
  Select_Lex *select_lex= &session->lex->select_lex;
601
571
  Name_resolution_context *context= &select_lex->context;
602
572
  Name_resolution_context_state ctx_state;
603
573
  bool insert_into_view= (0 != 0);
612
582
    inserting (for INSERT ... SELECT this is done by changing table_list,
613
583
    because INSERT ... SELECT share Select_Lex it with SELECT.
614
584
  */
615
 
  if (not select_insert)
 
585
  if (!select_insert)
616
586
  {
617
587
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
618
588
         un;
634
604
      return(true);
635
605
  }
636
606
 
637
 
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
 
607
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
638
608
    return(true);
639
609
 
640
610
 
660
630
 
661
631
    if (!res && check_fields)
662
632
    {
663
 
      bool saved_abort_on_warning= session->abortOnWarning();
664
 
 
665
 
      session->setAbortOnWarning(abort_on_warning);
 
633
      bool saved_abort_on_warning= session->abort_on_warning;
 
634
      session->abort_on_warning= abort_on_warning;
666
635
      res= check_that_all_fields_are_given_values(session,
667
636
                                                  table ? table :
668
637
                                                  context->table_list->table,
669
638
                                                  context->table_list);
670
 
      session->setAbortOnWarning(saved_abort_on_warning);
 
639
      session->abort_on_warning= saved_abort_on_warning;
671
640
    }
672
641
 
673
642
    if (!res && duplic == DUP_UPDATE)
678
647
    /* Restore the current context. */
679
648
    ctx_state.restore_state(context, table_list);
680
649
 
681
 
    if (not res)
 
650
    if (!res)
682
651
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
683
652
  }
684
653
 
685
654
  if (res)
686
655
    return(res);
687
656
 
688
 
  if (not table)
 
657
  if (!table)
689
658
    table= table_list->table;
690
659
 
691
 
  if (not select_insert)
 
660
  if (!select_insert)
692
661
  {
693
662
    TableList *duplicate;
694
663
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
698
667
      return true;
699
668
    }
700
669
  }
701
 
 
702
670
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
703
671
    table->prepare_for_position();
704
672
 
748
716
{
749
717
  int error;
750
718
  std::vector<unsigned char> key;
751
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
 
719
  MyBitmap *save_read_set, *save_write_set;
752
720
  uint64_t prev_insert_id= table->cursor->next_insert_id;
753
721
  uint64_t insert_id_for_cur_row= 0;
754
722
 
850
818
          table->cursor->adjust_next_insert_id_after_explicit_value(
851
819
            table->next_number_field->val_int());
852
820
        info->touched++;
853
 
 
854
 
        if (! table->records_are_comparable() || table->compare_records())
 
821
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
822
             !bitmap_is_subset(table->write_set, table->read_set)) ||
 
823
            table->compare_record())
855
824
        {
856
825
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
857
826
                                                table->getInsertRecord())) &&
872
841
          /*
873
842
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
874
843
            like a regular UPDATE statement: it should not affect the value of a
875
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
844
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
876
845
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
877
846
            handled separately by Session::arg_of_last_insert_id_function.
878
847
          */
941
910
    */
942
911
    if (table->read_set != save_read_set ||
943
912
        table->write_set != save_write_set)
944
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
913
      table->column_bitmaps_set(save_read_set, save_write_set);
945
914
  }
946
915
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
947
916
  {
964
933
err:
965
934
  info->last_errno= error;
966
935
  /* 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
 
936
  if (session->lex->current_select)
 
937
    session->lex->current_select->no_error= 0;        // Give error
969
938
  table->print_error(error,MYF(0));
970
939
 
971
940
before_err:
972
941
  table->cursor->restore_auto_increment(prev_insert_id);
973
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
974
 
  return 1;
 
942
  table->column_bitmaps_set(save_read_set, save_write_set);
 
943
  return(1);
975
944
}
976
945
 
977
946
 
1018
987
      }
1019
988
    }
1020
989
  }
1021
 
  return session->abortOnWarning() ? err : 0;
 
990
  return session->abort_on_warning ? err : 0;
1022
991
}
1023
992
 
1024
993
/***************************************************************************
1030
999
  make insert specific preparation and checks after opening tables
1031
1000
 
1032
1001
  SYNOPSIS
1033
 
    insert_select_prepare()
 
1002
    mysql_insert_select_prepare()
1034
1003
    session         thread handler
1035
1004
 
1036
1005
  RETURN
1038
1007
    true  Error
1039
1008
*/
1040
1009
 
1041
 
bool insert_select_prepare(Session *session)
 
1010
bool mysql_insert_select_prepare(Session *session)
1042
1011
{
1043
 
  LEX *lex= session->getLex();
 
1012
  LEX *lex= session->lex;
1044
1013
  Select_Lex *select_lex= &lex->select_lex;
1045
1014
 
1046
1015
  /*
1048
1017
    clause if table is VIEW
1049
1018
  */
1050
1019
 
1051
 
  if (prepare_insert(session, lex->query_tables,
 
1020
  if (mysql_prepare_insert(session, lex->query_tables,
1052
1021
                           lex->query_tables->table, lex->field_list, 0,
1053
1022
                           lex->update_list, lex->value_list,
1054
1023
                           lex->duplicates,
1087
1056
int
1088
1057
select_insert::prepare(List<Item> &values, Select_Lex_Unit *u)
1089
1058
{
 
1059
  LEX *lex= session->lex;
1090
1060
  int res;
1091
1061
  table_map map= 0;
1092
 
  Select_Lex *lex_current_select_save= session->getLex()->current_select;
 
1062
  Select_Lex *lex_current_select_save= lex->current_select;
1093
1063
 
1094
1064
 
1095
1065
  unit= u;
1099
1069
    select, LEX::current_select should point to the first select while
1100
1070
    we are fixing fields from insert list.
1101
1071
  */
1102
 
  session->getLex()->current_select= &session->getLex()->select_lex;
 
1072
  lex->current_select= &lex->select_lex;
1103
1073
  res= check_insert_fields(session, table_list, *fields, values,
1104
1074
                           !insert_into_view, &map) ||
1105
1075
       setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0);
1106
1076
 
1107
1077
  if (!res && fields->elements)
1108
1078
  {
1109
 
    bool saved_abort_on_warning= session->abortOnWarning();
1110
 
    session->setAbortOnWarning(not info.ignore);
 
1079
    bool saved_abort_on_warning= session->abort_on_warning;
 
1080
    session->abort_on_warning= !info.ignore;
1111
1081
    res= check_that_all_fields_are_given_values(session, table_list->table,
1112
1082
                                                table_list);
1113
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1083
    session->abort_on_warning= saved_abort_on_warning;
1114
1084
  }
1115
1085
 
1116
1086
  if (info.handle_duplicates == DUP_UPDATE && !res)
1117
1087
  {
1118
 
    Name_resolution_context *context= &session->getLex()->select_lex.context;
 
1088
    Name_resolution_context *context= &lex->select_lex.context;
1119
1089
    Name_resolution_context_state ctx_state;
1120
1090
 
1121
1091
    /* Save the state of the current name resolution context. */
1133
1103
      We use next_name_resolution_table descructively, so check it first (views?)
1134
1104
    */
1135
1105
    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)
 
1106
    if (lex->select_lex.group_list.elements == 0 &&
 
1107
        !lex->select_lex.with_sum_func)
1138
1108
      /*
1139
1109
        We must make a single context out of the two separate name resolution contexts :
1140
1110
        the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
1153
1123
        order to get correct values from those fields when the select
1154
1124
        employs a temporary table.
1155
1125
      */
1156
 
      List<Item>::iterator li(info.update_values->begin());
 
1126
      List_iterator<Item> li(*info.update_values);
1157
1127
      Item *item;
1158
1128
 
1159
1129
      while ((item= li++))
1160
1130
      {
1161
1131
        item->transform(&Item::update_value_transformer,
1162
 
                        (unsigned char*)session->getLex()->current_select);
 
1132
                        (unsigned char*)lex->current_select);
1163
1133
      }
1164
1134
    }
1165
1135
 
1167
1137
    ctx_state.restore_state(context, table_list);
1168
1138
  }
1169
1139
 
1170
 
  session->getLex()->current_select= lex_current_select_save;
 
1140
  lex->current_select= lex_current_select_save;
1171
1141
  if (res)
1172
1142
    return(1);
1173
1143
  /*
1183
1153
  if (unique_table(table_list, table_list->next_global))
1184
1154
  {
1185
1155
    /* 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;
 
1156
    lex->current_select->options|= OPTION_BUFFER_RESULT;
 
1157
    lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1188
1158
  }
1189
 
  else if (not (session->getLex()->current_select->options & OPTION_BUFFER_RESULT))
 
1159
  else if (!(lex->current_select->options & OPTION_BUFFER_RESULT))
1190
1160
  {
1191
1161
    /*
1192
1162
      We must not yet prepare the result table if it is the same as one of the
1203
1173
  table->next_number_field=table->found_next_number_field;
1204
1174
 
1205
1175
  session->cuted_fields=0;
1206
 
 
1207
1176
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1208
1177
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1209
 
 
1210
1178
  if (info.handle_duplicates == DUP_REPLACE)
1211
1179
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1212
 
 
1213
1180
  if (info.handle_duplicates == DUP_UPDATE)
1214
1181
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1215
 
 
1216
 
  session->setAbortOnWarning(not info.ignore);
 
1182
  session->abort_on_warning= !info.ignore;
1217
1183
  table->mark_columns_needed_for_insert();
1218
1184
 
1219
1185
 
1239
1205
 
1240
1206
int select_insert::prepare2(void)
1241
1207
{
1242
 
  if (session->getLex()->current_select->options & OPTION_BUFFER_RESULT)
 
1208
 
 
1209
  if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1243
1210
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
1244
 
 
1245
1211
  return(0);
1246
1212
}
1247
1213
 
1262
1228
    table->cursor->ha_reset();
1263
1229
  }
1264
1230
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1265
 
  session->setAbortOnWarning(false);
 
1231
  session->abort_on_warning= 0;
1266
1232
  return;
1267
1233
}
1268
1234
 
1270
1236
bool select_insert::send_data(List<Item> &values)
1271
1237
{
1272
1238
 
1273
 
  bool error= false;
 
1239
  bool error=0;
1274
1240
 
1275
1241
  if (unit->offset_limit_cnt)
1276
1242
  {                                             // using limit offset,count
1277
1243
    unit->offset_limit_cnt--;
1278
 
    return false;
 
1244
    return(0);
1279
1245
  }
1280
1246
 
1281
1247
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1282
1248
  store_values(values);
1283
1249
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1284
1250
  if (session->is_error())
1285
 
    return true;
 
1251
    return(1);
1286
1252
 
1287
1253
  // Release latches in case bulk insert takes a long time
1288
1254
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1332
1298
    fill_record(session, table->getFields(), values, true);
1333
1299
}
1334
1300
 
1335
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1301
void select_insert::send_error(uint32_t errcode,const char *err)
1336
1302
{
 
1303
 
 
1304
 
1337
1305
  my_message(errcode, err, MYF(0));
 
1306
 
 
1307
  return;
1338
1308
}
1339
1309
 
1340
1310
 
1383
1353
    (session->arg_of_last_insert_id_function ?
1384
1354
     session->first_successful_insert_id_in_prev_stmt :
1385
1355
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1386
 
  session->my_ok((ulong) session->rowCount(),
 
1356
  session->my_ok((ulong) session->row_count_func,
1387
1357
                 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());
 
1358
  session->status_var.inserted_row_count+= session->row_count_func; 
 
1359
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1390
1360
  return 0;
1391
1361
}
1392
1362
 
1488
1458
                                      List<Item> *items,
1489
1459
                                      bool is_if_not_exists,
1490
1460
                                      DrizzleLock **lock,
1491
 
                                      identifier::Table::const_reference identifier)
 
1461
                                      TableIdentifier &identifier)
1492
1462
{
 
1463
  Table tmp_table;              // Used during 'CreateField()'
1493
1464
  TableShare share(message::Table::INTERNAL);
 
1465
  Table *table= 0;
1494
1466
  uint32_t select_field_count= items->elements;
1495
1467
  /* Add selected items to field list */
1496
 
  List<Item>::iterator it(items->begin());
 
1468
  List_iterator_fast<Item> it(*items);
1497
1469
  Item *item;
1498
1470
  Field *tmp_field;
 
1471
  bool not_used;
1499
1472
 
1500
1473
  if (not (identifier.isTmp()) && create_table->table->db_stat)
1501
1474
  {
1505
1478
      create_info->table_existed= 1;            // Mark that table existed
1506
1479
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1507
1480
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1508
 
                          create_table->getTableName());
 
1481
                          create_table->table_name);
1509
1482
      return create_table->table;
1510
1483
    }
1511
1484
 
1512
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1485
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1513
1486
    return NULL;
1514
1487
  }
1515
1488
 
 
1489
  tmp_table.timestamp_field= 0;
 
1490
  tmp_table.setShare(&share);
 
1491
 
 
1492
  tmp_table.getMutableShare()->db_create_options= 0;
 
1493
  tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
 
1494
 
 
1495
  if (not table_proto.engine().name().compare("MyISAM"))
 
1496
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1497
  else if (not table_proto.engine().name().compare("MEMORY"))
 
1498
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1499
 
 
1500
  tmp_table.null_row= false;
 
1501
  tmp_table.maybe_null= false;
 
1502
 
 
1503
  while ((item=it++))
1516
1504
  {
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
 
      }
 
1505
    CreateField *cr_field;
 
1506
    Field *field, *def_field;
 
1507
    if (item->type() == Item::FUNC_ITEM)
 
1508
      if (item->result_type() != STRING_RESULT)
 
1509
        field= item->tmp_table_field(&tmp_table);
1541
1510
      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
 
    }
 
1511
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1512
    else
 
1513
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1514
                              (Item ***) 0, &tmp_field, &def_field, false,
 
1515
                              false, false, 0);
 
1516
    if (!field ||
 
1517
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1518
                                           ((Item_field *)item)->field :
 
1519
                                           (Field*) 0))))
 
1520
      return NULL;
 
1521
    if (item->maybe_null)
 
1522
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1523
    alter_info->create_list.push_back(cr_field);
1563
1524
  }
1564
1525
 
1565
1526
  /*
1569
1530
    creating base table on which name we have exclusive lock. So code below
1570
1531
    should not cause deadlocks or races.
1571
1532
  */
1572
 
  Table *table= 0;
1573
1533
  {
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))
 
1534
    if (not mysql_create_table_no_lock(session,
 
1535
                                       identifier,
 
1536
                                       create_info,
 
1537
                                       table_proto,
 
1538
                                       alter_info,
 
1539
                                       false,
 
1540
                                       select_field_count,
 
1541
                                       is_if_not_exists))
1582
1542
    {
1583
1543
      if (create_info->table_existed && not identifier.isTmp())
1584
1544
      {
1587
1547
          or it was created via different mysqld front-end to the
1588
1548
          cluster. We don't have much options but throw an error.
1589
1549
        */
1590
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1550
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1591
1551
        return NULL;
1592
1552
      }
1593
1553
 
1594
1554
      if (not identifier.isTmp())
1595
1555
      {
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)
 
1556
        LOCK_open.lock(); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1557
        if (session->reopen_name_locked_table(create_table, false))
1600
1558
        {
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
 
          }
 
1559
          quick_rm_table(*session, identifier);
1611
1560
        }
1612
1561
        else
1613
 
        {
1614
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
1615
 
        }
 
1562
          table= create_table->table;
 
1563
        LOCK_open.unlock();
1616
1564
      }
1617
1565
      else
1618
1566
      {
1625
1573
            it preparable for open. But let us do close_temporary_table() here
1626
1574
            just in case.
1627
1575
          */
1628
 
          session->drop_temporary_table(identifier);
 
1576
          session->drop_temporary_table(create_table);
1629
1577
        }
1630
1578
      }
1631
1579
    }
1632
 
    if (not table)                                   // open failed
 
1580
    if (!table)                                   // open failed
1633
1581
      return NULL;
1634
1582
  }
1635
1583
 
1636
1584
  table->reginfo.lock_type=TL_WRITE;
1637
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1585
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1586
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1638
1587
  {
1639
1588
    if (*lock)
1640
1589
    {
1641
 
      session->unlockTables(*lock);
 
1590
      mysql_unlock_tables(session, *lock);
1642
1591
      *lock= 0;
1643
1592
    }
1644
1593
 
1645
1594
    if (not create_info->table_existed)
1646
1595
      session->drop_open_table(table, identifier);
1647
 
 
1648
1596
    return NULL;
1649
1597
  }
1650
1598
 
1700
1648
 
1701
1649
  /* Mark all fields that are given values */
1702
1650
  for (Field **f= field ; *f ; f++)
1703
 
  {
1704
 
    table->setWriteSet((*f)->position());
1705
 
  }
 
1651
    table->setWriteSet((*f)->field_index);
1706
1652
 
1707
1653
  /* Don't set timestamp if used */
1708
1654
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1712
1658
  session->cuted_fields=0;
1713
1659
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1714
1660
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1715
 
 
1716
1661
  if (info.handle_duplicates == DUP_REPLACE)
1717
1662
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1718
 
 
1719
1663
  if (info.handle_duplicates == DUP_UPDATE)
1720
1664
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1721
 
 
1722
1665
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1723
 
  session->setAbortOnWarning(not info.ignore);
 
1666
  session->abort_on_warning= !info.ignore;
1724
1667
  if (check_that_all_fields_are_given_values(session, table, table_list))
1725
1668
    return(1);
1726
 
 
1727
1669
  table->mark_columns_needed_for_insert();
1728
1670
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1729
1671
  return(0);
1735
1677
}
1736
1678
 
1737
1679
 
1738
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1680
void select_create::send_error(uint32_t errcode,const char *err)
1739
1681
{
1740
1682
  /*
1741
1683
    This will execute any rollbacks that are necessary before writing
1749
1691
 
1750
1692
  */
1751
1693
  select_insert::send_error(errcode, err);
 
1694
 
 
1695
  return;
1752
1696
}
1753
1697
 
1754
1698
 
1767
1711
    if (!table->getShare()->getType())
1768
1712
    {
1769
1713
      TransactionServices &transaction_services= TransactionServices::singleton();
1770
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1714
      transaction_services.autocommitOrRollback(session, 0);
1771
1715
      (void) session->endActiveTransaction();
1772
1716
    }
1773
1717
 
1775
1719
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1776
1720
    if (m_plock)
1777
1721
    {
1778
 
      session->unlockTables(*m_plock);
 
1722
      mysql_unlock_tables(session, *m_plock);
1779
1723
      *m_plock= NULL;
1780
1724
      m_plock= NULL;
1781
1725
    }
1805
1749
 
1806
1750
  if (m_plock)
1807
1751
  {
1808
 
    session->unlockTables(*m_plock);
 
1752
    mysql_unlock_tables(session, *m_plock);
1809
1753
    *m_plock= NULL;
1810
1754
    m_plock= NULL;
1811
1755
  }