~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Brian Aker
  • Date: 2010-10-09 17:44:13 UTC
  • mto: This revision was merged to the branch mainline in revision 1853.
  • Revision ID: brian@tangent.org-20101009174413-4cs0q58kw0fjd45y
First pass through adding back user_locks.

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->test(table->timestamp_field->field_index);
 
172
    table->write_set->reset(table->timestamp_field->field_index);
177
173
  }
178
174
 
179
175
  /* Check the fields we are going to modify */
191
187
 
192
188
    if (timestamp_mark)
193
189
    {
194
 
      table->setWriteSet(table->timestamp_field->position());
 
190
      table->setWriteSet(table->timestamp_field->field_index);
195
191
    }
196
192
  }
197
193
  return 0;
229
225
  end of dispatch_command().
230
226
*/
231
227
 
232
 
bool insert_query(Session *session,TableList *table_list,
 
228
bool mysql_insert(Session *session,TableList *table_list,
233
229
                  List<Item> &fields,
234
230
                  List<List_item> &values_list,
235
231
                  List<Item> &update_fields,
245
241
  uint64_t id;
246
242
  CopyInfo info;
247
243
  Table *table= 0;
248
 
  List<List_item>::iterator its(values_list.begin());
 
244
  List_iterator_fast<List_item> its(values_list);
249
245
  List_item *values;
250
246
  Name_resolution_context *context;
251
247
  Name_resolution_context_state ctx_state;
273
269
  values= its++;
274
270
  value_count= values->elements;
275
271
 
276
 
  if (prepare_insert(session, table_list, table, fields, values,
 
272
  if (mysql_prepare_insert(session, table_list, table, fields, values,
277
273
                           update_fields, update_values, duplic, &unused_conds,
278
274
                           false,
279
275
                           (fields.elements || !value_count ||
280
276
                            (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
 
  }
 
277
    goto abort;
290
278
 
291
279
  /* mysql_prepare_insert set table_list->table if it was not set */
292
280
  table= table_list->table;
293
281
 
294
 
  context= &session->getLex()->select_lex.context;
 
282
  context= &session->lex->select_lex.context;
295
283
  /*
296
284
    These three asserts test the hypothesis that the resetting of the name
297
285
    resolution context below is not necessary at all since the list of local
317
305
    if (values->elements != value_count)
318
306
    {
319
307
      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;
 
308
      goto abort;
329
309
    }
330
310
    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
 
    }
 
311
      goto abort;
340
312
  }
341
 
  its= values_list.begin();
 
313
  its.rewind ();
342
314
 
343
315
  /* Restore the current context. */
344
316
  ctx_state.restore_state(context, table_list);
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
 
850
819
          table->cursor->adjust_next_insert_id_after_explicit_value(
851
820
            table->next_number_field->val_int());
852
821
        info->touched++;
853
 
 
854
 
        if (! table->records_are_comparable() || table->compare_records())
 
822
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
823
            ! table->write_set->is_subset_of(*table->read_set)) ||
 
824
            table->compare_record())
855
825
        {
856
826
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
857
827
                                                table->getInsertRecord())) &&
872
842
          /*
873
843
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
874
844
            like a regular UPDATE statement: it should not affect the value of a
875
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
845
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
876
846
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
877
847
            handled separately by Session::arg_of_last_insert_id_function.
878
848
          */
964
934
err:
965
935
  info->last_errno= error;
966
936
  /* 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
 
937
  if (session->lex->current_select)
 
938
    session->lex->current_select->no_error= 0;        // Give error
969
939
  table->print_error(error,MYF(0));
970
940
 
971
941
before_err:
1018
988
      }
1019
989
    }
1020
990
  }
1021
 
  return session->abortOnWarning() ? err : 0;
 
991
  return session->abort_on_warning ? err : 0;
1022
992
}
1023
993
 
1024
994
/***************************************************************************
1030
1000
  make insert specific preparation and checks after opening tables
1031
1001
 
1032
1002
  SYNOPSIS
1033
 
    insert_select_prepare()
 
1003
    mysql_insert_select_prepare()
1034
1004
    session         thread handler
1035
1005
 
1036
1006
  RETURN
1038
1008
    true  Error
1039
1009
*/
1040
1010
 
1041
 
bool insert_select_prepare(Session *session)
 
1011
bool mysql_insert_select_prepare(Session *session)
1042
1012
{
1043
 
  LEX *lex= session->getLex();
 
1013
  LEX *lex= session->lex;
1044
1014
  Select_Lex *select_lex= &lex->select_lex;
1045
1015
 
1046
1016
  /*
1048
1018
    clause if table is VIEW
1049
1019
  */
1050
1020
 
1051
 
  if (prepare_insert(session, lex->query_tables,
 
1021
  if (mysql_prepare_insert(session, lex->query_tables,
1052
1022
                           lex->query_tables->table, lex->field_list, 0,
1053
1023
                           lex->update_list, lex->value_list,
1054
1024
                           lex->duplicates,
1087
1057
int
1088
1058
select_insert::prepare(List<Item> &values, Select_Lex_Unit *u)
1089
1059
{
 
1060
  LEX *lex= session->lex;
1090
1061
  int res;
1091
1062
  table_map map= 0;
1092
 
  Select_Lex *lex_current_select_save= session->getLex()->current_select;
 
1063
  Select_Lex *lex_current_select_save= lex->current_select;
1093
1064
 
1094
1065
 
1095
1066
  unit= u;
1099
1070
    select, LEX::current_select should point to the first select while
1100
1071
    we are fixing fields from insert list.
1101
1072
  */
1102
 
  session->getLex()->current_select= &session->getLex()->select_lex;
 
1073
  lex->current_select= &lex->select_lex;
1103
1074
  res= check_insert_fields(session, table_list, *fields, values,
1104
1075
                           !insert_into_view, &map) ||
1105
1076
       setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0);
1106
1077
 
1107
1078
  if (!res && fields->elements)
1108
1079
  {
1109
 
    bool saved_abort_on_warning= session->abortOnWarning();
1110
 
    session->setAbortOnWarning(not info.ignore);
 
1080
    bool saved_abort_on_warning= session->abort_on_warning;
 
1081
    session->abort_on_warning= !info.ignore;
1111
1082
    res= check_that_all_fields_are_given_values(session, table_list->table,
1112
1083
                                                table_list);
1113
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1084
    session->abort_on_warning= saved_abort_on_warning;
1114
1085
  }
1115
1086
 
1116
1087
  if (info.handle_duplicates == DUP_UPDATE && !res)
1117
1088
  {
1118
 
    Name_resolution_context *context= &session->getLex()->select_lex.context;
 
1089
    Name_resolution_context *context= &lex->select_lex.context;
1119
1090
    Name_resolution_context_state ctx_state;
1120
1091
 
1121
1092
    /* Save the state of the current name resolution context. */
1133
1104
      We use next_name_resolution_table descructively, so check it first (views?)
1134
1105
    */
1135
1106
    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)
 
1107
    if (lex->select_lex.group_list.elements == 0 &&
 
1108
        !lex->select_lex.with_sum_func)
1138
1109
      /*
1139
1110
        We must make a single context out of the two separate name resolution contexts :
1140
1111
        the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
1153
1124
        order to get correct values from those fields when the select
1154
1125
        employs a temporary table.
1155
1126
      */
1156
 
      List<Item>::iterator li(info.update_values->begin());
 
1127
      List_iterator<Item> li(*info.update_values);
1157
1128
      Item *item;
1158
1129
 
1159
1130
      while ((item= li++))
1160
1131
      {
1161
1132
        item->transform(&Item::update_value_transformer,
1162
 
                        (unsigned char*)session->getLex()->current_select);
 
1133
                        (unsigned char*)lex->current_select);
1163
1134
      }
1164
1135
    }
1165
1136
 
1167
1138
    ctx_state.restore_state(context, table_list);
1168
1139
  }
1169
1140
 
1170
 
  session->getLex()->current_select= lex_current_select_save;
 
1141
  lex->current_select= lex_current_select_save;
1171
1142
  if (res)
1172
1143
    return(1);
1173
1144
  /*
1183
1154
  if (unique_table(table_list, table_list->next_global))
1184
1155
  {
1185
1156
    /* 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;
 
1157
    lex->current_select->options|= OPTION_BUFFER_RESULT;
 
1158
    lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1188
1159
  }
1189
 
  else if (not (session->getLex()->current_select->options & OPTION_BUFFER_RESULT))
 
1160
  else if (!(lex->current_select->options & OPTION_BUFFER_RESULT))
1190
1161
  {
1191
1162
    /*
1192
1163
      We must not yet prepare the result table if it is the same as one of the
1203
1174
  table->next_number_field=table->found_next_number_field;
1204
1175
 
1205
1176
  session->cuted_fields=0;
1206
 
 
1207
1177
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1208
1178
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1209
 
 
1210
1179
  if (info.handle_duplicates == DUP_REPLACE)
1211
1180
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1212
 
 
1213
1181
  if (info.handle_duplicates == DUP_UPDATE)
1214
1182
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1215
 
 
1216
 
  session->setAbortOnWarning(not info.ignore);
 
1183
  session->abort_on_warning= !info.ignore;
1217
1184
  table->mark_columns_needed_for_insert();
1218
1185
 
1219
1186
 
1239
1206
 
1240
1207
int select_insert::prepare2(void)
1241
1208
{
1242
 
  if (session->getLex()->current_select->options & OPTION_BUFFER_RESULT)
 
1209
 
 
1210
  if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1243
1211
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
1244
 
 
1245
1212
  return(0);
1246
1213
}
1247
1214
 
1262
1229
    table->cursor->ha_reset();
1263
1230
  }
1264
1231
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1265
 
  session->setAbortOnWarning(false);
 
1232
  session->abort_on_warning= 0;
1266
1233
  return;
1267
1234
}
1268
1235
 
1270
1237
bool select_insert::send_data(List<Item> &values)
1271
1238
{
1272
1239
 
1273
 
  bool error= false;
 
1240
  bool error=0;
1274
1241
 
1275
1242
  if (unit->offset_limit_cnt)
1276
1243
  {                                             // using limit offset,count
1277
1244
    unit->offset_limit_cnt--;
1278
 
    return false;
 
1245
    return(0);
1279
1246
  }
1280
1247
 
1281
1248
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1282
1249
  store_values(values);
1283
1250
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1284
1251
  if (session->is_error())
1285
 
    return true;
 
1252
    return(1);
1286
1253
 
1287
1254
  // Release latches in case bulk insert takes a long time
1288
1255
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1332
1299
    fill_record(session, table->getFields(), values, true);
1333
1300
}
1334
1301
 
1335
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1302
void select_insert::send_error(uint32_t errcode,const char *err)
1336
1303
{
 
1304
 
 
1305
 
1337
1306
  my_message(errcode, err, MYF(0));
 
1307
 
 
1308
  return;
1338
1309
}
1339
1310
 
1340
1311
 
1383
1354
    (session->arg_of_last_insert_id_function ?
1384
1355
     session->first_successful_insert_id_in_prev_stmt :
1385
1356
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1386
 
  session->my_ok((ulong) session->rowCount(),
 
1357
  session->my_ok((ulong) session->row_count_func,
1387
1358
                 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());
 
1359
  session->status_var.inserted_row_count+= session->row_count_func; 
 
1360
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1390
1361
  return 0;
1391
1362
}
1392
1363
 
1488
1459
                                      List<Item> *items,
1489
1460
                                      bool is_if_not_exists,
1490
1461
                                      DrizzleLock **lock,
1491
 
                                      identifier::Table::const_reference identifier)
 
1462
                                      TableIdentifier &identifier)
1492
1463
{
 
1464
  Table tmp_table;              // Used during 'CreateField()'
1493
1465
  TableShare share(message::Table::INTERNAL);
 
1466
  Table *table= 0;
1494
1467
  uint32_t select_field_count= items->elements;
1495
1468
  /* Add selected items to field list */
1496
 
  List<Item>::iterator it(items->begin());
 
1469
  List_iterator_fast<Item> it(*items);
1497
1470
  Item *item;
1498
1471
  Field *tmp_field;
 
1472
  bool not_used;
1499
1473
 
1500
1474
  if (not (identifier.isTmp()) && create_table->table->db_stat)
1501
1475
  {
1505
1479
      create_info->table_existed= 1;            // Mark that table existed
1506
1480
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1507
1481
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1508
 
                          create_table->getTableName());
 
1482
                          create_table->table_name);
1509
1483
      return create_table->table;
1510
1484
    }
1511
1485
 
1512
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1486
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1513
1487
    return NULL;
1514
1488
  }
1515
1489
 
 
1490
  tmp_table.timestamp_field= 0;
 
1491
  tmp_table.setShare(&share);
 
1492
 
 
1493
  tmp_table.getMutableShare()->db_create_options= 0;
 
1494
  tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
 
1495
 
 
1496
  if (not table_proto.engine().name().compare("MyISAM"))
 
1497
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1498
  else if (not table_proto.engine().name().compare("MEMORY"))
 
1499
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1500
 
 
1501
  tmp_table.null_row= false;
 
1502
  tmp_table.maybe_null= false;
 
1503
 
 
1504
  while ((item=it++))
1516
1505
  {
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
 
      }
 
1506
    CreateField *cr_field;
 
1507
    Field *field, *def_field;
 
1508
    if (item->type() == Item::FUNC_ITEM)
 
1509
      if (item->result_type() != STRING_RESULT)
 
1510
        field= item->tmp_table_field(&tmp_table);
1541
1511
      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
 
    }
 
1512
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1513
    else
 
1514
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1515
                              (Item ***) 0, &tmp_field, &def_field, false,
 
1516
                              false, false, 0);
 
1517
    if (!field ||
 
1518
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1519
                                           ((Item_field *)item)->field :
 
1520
                                           (Field*) 0))))
 
1521
      return NULL;
 
1522
    if (item->maybe_null)
 
1523
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1524
    alter_info->create_list.push_back(cr_field);
1563
1525
  }
1564
1526
 
1565
1527
  /*
1569
1531
    creating base table on which name we have exclusive lock. So code below
1570
1532
    should not cause deadlocks or races.
1571
1533
  */
1572
 
  Table *table= 0;
1573
1534
  {
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))
 
1535
    if (not mysql_create_table_no_lock(session,
 
1536
                                       identifier,
 
1537
                                       create_info,
 
1538
                                       table_proto,
 
1539
                                       alter_info,
 
1540
                                       false,
 
1541
                                       select_field_count,
 
1542
                                       is_if_not_exists))
1582
1543
    {
1583
1544
      if (create_info->table_existed && not identifier.isTmp())
1584
1545
      {
1587
1548
          or it was created via different mysqld front-end to the
1588
1549
          cluster. We don't have much options but throw an error.
1589
1550
        */
1590
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1551
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1591
1552
        return NULL;
1592
1553
      }
1593
1554
 
1594
1555
      if (not identifier.isTmp())
1595
1556
      {
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)
 
1557
        LOCK_open.lock(); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1558
        if (session->reopen_name_locked_table(create_table, false))
1600
1559
        {
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
 
          }
 
1560
          quick_rm_table(*session, identifier);
1611
1561
        }
1612
1562
        else
1613
 
        {
1614
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
1615
 
        }
 
1563
          table= create_table->table;
 
1564
        LOCK_open.unlock();
1616
1565
      }
1617
1566
      else
1618
1567
      {
1625
1574
            it preparable for open. But let us do close_temporary_table() here
1626
1575
            just in case.
1627
1576
          */
1628
 
          session->drop_temporary_table(identifier);
 
1577
          session->drop_temporary_table(create_table);
1629
1578
        }
1630
1579
      }
1631
1580
    }
1632
 
    if (not table)                                   // open failed
 
1581
    if (!table)                                   // open failed
1633
1582
      return NULL;
1634
1583
  }
1635
1584
 
1636
1585
  table->reginfo.lock_type=TL_WRITE;
1637
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1586
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1587
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1638
1588
  {
1639
1589
    if (*lock)
1640
1590
    {
1641
 
      session->unlockTables(*lock);
 
1591
      mysql_unlock_tables(session, *lock);
1642
1592
      *lock= 0;
1643
1593
    }
1644
1594
 
1645
1595
    if (not create_info->table_existed)
1646
1596
      session->drop_open_table(table, identifier);
1647
 
 
1648
1597
    return NULL;
1649
1598
  }
1650
1599
 
1700
1649
 
1701
1650
  /* Mark all fields that are given values */
1702
1651
  for (Field **f= field ; *f ; f++)
1703
 
  {
1704
 
    table->setWriteSet((*f)->position());
1705
 
  }
 
1652
    table->setWriteSet((*f)->field_index);
1706
1653
 
1707
1654
  /* Don't set timestamp if used */
1708
1655
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1712
1659
  session->cuted_fields=0;
1713
1660
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1714
1661
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1715
 
 
1716
1662
  if (info.handle_duplicates == DUP_REPLACE)
1717
1663
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1718
 
 
1719
1664
  if (info.handle_duplicates == DUP_UPDATE)
1720
1665
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1721
 
 
1722
1666
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1723
 
  session->setAbortOnWarning(not info.ignore);
 
1667
  session->abort_on_warning= !info.ignore;
1724
1668
  if (check_that_all_fields_are_given_values(session, table, table_list))
1725
1669
    return(1);
1726
 
 
1727
1670
  table->mark_columns_needed_for_insert();
1728
1671
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1729
1672
  return(0);
1735
1678
}
1736
1679
 
1737
1680
 
1738
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1681
void select_create::send_error(uint32_t errcode,const char *err)
1739
1682
{
1740
1683
  /*
1741
1684
    This will execute any rollbacks that are necessary before writing
1749
1692
 
1750
1693
  */
1751
1694
  select_insert::send_error(errcode, err);
 
1695
 
 
1696
  return;
1752
1697
}
1753
1698
 
1754
1699
 
1767
1712
    if (!table->getShare()->getType())
1768
1713
    {
1769
1714
      TransactionServices &transaction_services= TransactionServices::singleton();
1770
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1715
      transaction_services.autocommitOrRollback(session, 0);
1771
1716
      (void) session->endActiveTransaction();
1772
1717
    }
1773
1718
 
1775
1720
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1776
1721
    if (m_plock)
1777
1722
    {
1778
 
      session->unlockTables(*m_plock);
 
1723
      mysql_unlock_tables(session, *m_plock);
1779
1724
      *m_plock= NULL;
1780
1725
      m_plock= NULL;
1781
1726
    }
1805
1750
 
1806
1751
  if (m_plock)
1807
1752
  {
1808
 
    session->unlockTables(*m_plock);
 
1753
    mysql_unlock_tables(session, *m_plock);
1809
1754
    *m_plock= NULL;
1810
1755
    m_plock= NULL;
1811
1756
  }