~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Marisa Plumb
  • Date: 2010-12-04 02:38:29 UTC
  • mto: This revision was merged to the branch mainline in revision 1984.
  • Revision ID: marisa.plumb@gmail.com-20101204023829-2khzxh30wxi256db
updates to a few sql docs 

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>
 
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"
36
34
 
37
 
#include <drizzled/table/shell.h>
 
35
#include "drizzled/table/shell.h"
38
36
 
39
37
namespace drizzled
40
38
{
87
85
  }
88
86
  else
89
87
  {                                             // Part field list
90
 
    Select_Lex *select_lex= &session->getLex()->select_lex;
 
88
    Select_Lex *select_lex= &session->lex->select_lex;
91
89
    Name_resolution_context *context= &select_lex->context;
92
90
    Name_resolution_context_state ctx_state;
93
91
    int res;
131
129
      }
132
130
      else
133
131
      {
134
 
        table->setWriteSet(table->timestamp_field->position());
 
132
        table->setWriteSet(table->timestamp_field->field_index);
135
133
      }
136
134
    }
137
135
  }
172
170
      Unmark the timestamp field so that we can check if this is modified
173
171
      by update_fields
174
172
    */
175
 
    timestamp_mark= table->write_set->test(table->timestamp_field->position());
176
 
    table->write_set->reset(table->timestamp_field->position());
 
173
    timestamp_mark= table->write_set->test(table->timestamp_field->field_index);
 
174
    table->write_set->reset(table->timestamp_field->field_index);
177
175
  }
178
176
 
179
177
  /* Check the fields we are going to modify */
191
189
 
192
190
    if (timestamp_mark)
193
191
    {
194
 
      table->setWriteSet(table->timestamp_field->position());
 
192
      table->setWriteSet(table->timestamp_field->field_index);
195
193
    }
196
194
  }
197
195
  return 0;
229
227
  end of dispatch_command().
230
228
*/
231
229
 
232
 
bool insert_query(Session *session,TableList *table_list,
 
230
bool mysql_insert(Session *session,TableList *table_list,
233
231
                  List<Item> &fields,
234
232
                  List<List_item> &values_list,
235
233
                  List<Item> &update_fields,
245
243
  uint64_t id;
246
244
  CopyInfo info;
247
245
  Table *table= 0;
248
 
  List<List_item>::iterator its(values_list.begin());
 
246
  List_iterator_fast<List_item> its(values_list);
249
247
  List_item *values;
250
248
  Name_resolution_context *context;
251
249
  Name_resolution_context_state ctx_state;
273
271
  values= its++;
274
272
  value_count= values->elements;
275
273
 
276
 
  if (prepare_insert(session, table_list, table, fields, values,
 
274
  if (mysql_prepare_insert(session, table_list, table, fields, values,
277
275
                           update_fields, update_values, duplic, &unused_conds,
278
276
                           false,
279
277
                           (fields.elements || !value_count ||
282
280
    if (table != NULL)
283
281
      table->cursor->ha_release_auto_increment();
284
282
    if (!joins_freed)
285
 
      free_underlaid_joins(session, &session->getLex()->select_lex);
286
 
    session->setAbortOnWarning(false);
 
283
      free_underlaid_joins(session, &session->lex->select_lex);
 
284
    session->abort_on_warning= 0;
287
285
    DRIZZLE_INSERT_DONE(1, 0);
288
286
    return true;
289
287
  }
291
289
  /* mysql_prepare_insert set table_list->table if it was not set */
292
290
  table= table_list->table;
293
291
 
294
 
  context= &session->getLex()->select_lex.context;
 
292
  context= &session->lex->select_lex.context;
295
293
  /*
296
294
    These three asserts test the hypothesis that the resetting of the name
297
295
    resolution context below is not necessary at all since the list of local
321
319
      if (table != NULL)
322
320
        table->cursor->ha_release_auto_increment();
323
321
      if (!joins_freed)
324
 
        free_underlaid_joins(session, &session->getLex()->select_lex);
325
 
      session->setAbortOnWarning(false);
 
322
        free_underlaid_joins(session, &session->lex->select_lex);
 
323
      session->abort_on_warning= 0;
326
324
      DRIZZLE_INSERT_DONE(1, 0);
327
325
 
328
326
      return true;
332
330
      if (table != NULL)
333
331
        table->cursor->ha_release_auto_increment();
334
332
      if (!joins_freed)
335
 
        free_underlaid_joins(session, &session->getLex()->select_lex);
336
 
      session->setAbortOnWarning(false);
 
333
        free_underlaid_joins(session, &session->lex->select_lex);
 
334
      session->abort_on_warning= 0;
337
335
      DRIZZLE_INSERT_DONE(1, 0);
338
336
      return true;
339
337
    }
340
338
  }
341
 
  its= values_list.begin();
 
339
  its.rewind ();
342
340
 
343
341
  /* Restore the current context. */
344
342
  ctx_state.restore_state(context, table_list);
374
372
  }
375
373
 
376
374
 
377
 
  session->setAbortOnWarning(not ignore);
 
375
  session->abort_on_warning= !ignore;
378
376
 
379
377
  table->mark_columns_needed_for_insert();
380
378
 
424
422
    session->row_count++;
425
423
  }
426
424
 
427
 
  free_underlaid_joins(session, &session->getLex()->select_lex);
 
425
  free_underlaid_joins(session, &session->lex->select_lex);
428
426
  joins_freed= true;
429
427
 
430
428
  /*
484
482
    if (table != NULL)
485
483
      table->cursor->ha_release_auto_increment();
486
484
    if (!joins_freed)
487
 
      free_underlaid_joins(session, &session->getLex()->select_lex);
488
 
    session->setAbortOnWarning(false);
 
485
      free_underlaid_joins(session, &session->lex->select_lex);
 
486
    session->abort_on_warning= 0;
489
487
    DRIZZLE_INSERT_DONE(1, 0);
490
488
    return true;
491
489
  }
494
492
                                    !session->cuted_fields))
495
493
  {
496
494
    session->row_count_func= info.copied + info.deleted + info.updated;
497
 
    session->my_ok((ulong) session->rowCount(),
 
495
    session->my_ok((ulong) session->row_count_func,
498
496
                   info.copied + info.deleted + info.touched, id);
499
497
  }
500
498
  else
507
505
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
508
506
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
509
507
    session->row_count_func= info.copied + info.deleted + info.updated;
510
 
    session->my_ok((ulong) session->rowCount(),
 
508
    session->my_ok((ulong) session->row_count_func,
511
509
                   info.copied + info.deleted + info.touched, id, buff);
512
510
  }
513
 
  session->status_var.inserted_row_count+= session->rowCount();
514
 
  session->setAbortOnWarning(false);
515
 
  DRIZZLE_INSERT_DONE(0, session->rowCount());
 
511
  session->status_var.inserted_row_count+= session->row_count_func;
 
512
  session->abort_on_warning= 0;
 
513
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
516
514
 
517
515
  return false;
518
516
}
522
520
  Check if table can be updated
523
521
 
524
522
  SYNOPSIS
525
 
     prepare_insert_check_table()
 
523
     mysql_prepare_insert_check_table()
526
524
     session            Thread handle
527
525
     table_list         Table list
528
526
     fields             List of fields to be updated
534
532
     true  ERROR
535
533
*/
536
534
 
537
 
static bool prepare_insert_check_table(Session *session, TableList *table_list,
 
535
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
538
536
                                             List<Item> &,
539
537
                                             bool select_insert)
540
538
{
547
545
     than INSERT.
548
546
  */
549
547
 
550
 
  if (setup_tables_and_check_access(session, &session->getLex()->select_lex.context,
551
 
                                    &session->getLex()->select_lex.top_join_list,
 
548
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
549
                                    &session->lex->select_lex.top_join_list,
552
550
                                    table_list,
553
 
                                    &session->getLex()->select_lex.leaf_tables,
 
551
                                    &session->lex->select_lex.leaf_tables,
554
552
                                    select_insert))
555
553
    return(true);
556
554
 
562
560
  Prepare items in INSERT statement
563
561
 
564
562
  SYNOPSIS
565
 
    prepare_insert()
 
563
    mysql_prepare_insert()
566
564
    session                     Thread handler
567
565
    table_list          Global/local table list
568
566
    table               Table to insert into (can be NULL if table should
589
587
    true  error
590
588
*/
591
589
 
592
 
bool prepare_insert(Session *session, TableList *table_list,
 
590
bool mysql_prepare_insert(Session *session, TableList *table_list,
593
591
                          Table *table, List<Item> &fields, List_item *values,
594
592
                          List<Item> &update_fields, List<Item> &update_values,
595
593
                          enum_duplicates duplic,
597
595
                          bool select_insert,
598
596
                          bool check_fields, bool abort_on_warning)
599
597
{
600
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
598
  Select_Lex *select_lex= &session->lex->select_lex;
601
599
  Name_resolution_context *context= &select_lex->context;
602
600
  Name_resolution_context_state ctx_state;
603
601
  bool insert_into_view= (0 != 0);
612
610
    inserting (for INSERT ... SELECT this is done by changing table_list,
613
611
    because INSERT ... SELECT share Select_Lex it with SELECT.
614
612
  */
615
 
  if (not select_insert)
 
613
  if (!select_insert)
616
614
  {
617
615
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
618
616
         un;
634
632
      return(true);
635
633
  }
636
634
 
637
 
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
 
635
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
638
636
    return(true);
639
637
 
640
638
 
660
658
 
661
659
    if (!res && check_fields)
662
660
    {
663
 
      bool saved_abort_on_warning= session->abortOnWarning();
664
 
 
665
 
      session->setAbortOnWarning(abort_on_warning);
 
661
      bool saved_abort_on_warning= session->abort_on_warning;
 
662
      session->abort_on_warning= abort_on_warning;
666
663
      res= check_that_all_fields_are_given_values(session,
667
664
                                                  table ? table :
668
665
                                                  context->table_list->table,
669
666
                                                  context->table_list);
670
 
      session->setAbortOnWarning(saved_abort_on_warning);
 
667
      session->abort_on_warning= saved_abort_on_warning;
671
668
    }
672
669
 
673
670
    if (!res && duplic == DUP_UPDATE)
678
675
    /* Restore the current context. */
679
676
    ctx_state.restore_state(context, table_list);
680
677
 
681
 
    if (not res)
 
678
    if (!res)
682
679
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
683
680
  }
684
681
 
685
682
  if (res)
686
683
    return(res);
687
684
 
688
 
  if (not table)
 
685
  if (!table)
689
686
    table= table_list->table;
690
687
 
691
 
  if (not select_insert)
 
688
  if (!select_insert)
692
689
  {
693
690
    TableList *duplicate;
694
691
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
698
695
      return true;
699
696
    }
700
697
  }
701
 
 
702
698
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
703
699
    table->prepare_for_position();
704
700
 
850
846
          table->cursor->adjust_next_insert_id_after_explicit_value(
851
847
            table->next_number_field->val_int());
852
848
        info->touched++;
853
 
 
854
 
        if (! table->records_are_comparable() || table->compare_records())
 
849
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
850
            ! table->write_set->is_subset_of(*table->read_set)) ||
 
851
            table->compare_record())
855
852
        {
856
853
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
857
854
                                                table->getInsertRecord())) &&
872
869
          /*
873
870
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
874
871
            like a regular UPDATE statement: it should not affect the value of a
875
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
872
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
876
873
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
877
874
            handled separately by Session::arg_of_last_insert_id_function.
878
875
          */
964
961
err:
965
962
  info->last_errno= error;
966
963
  /* 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
 
964
  if (session->lex->current_select)
 
965
    session->lex->current_select->no_error= 0;        // Give error
969
966
  table->print_error(error,MYF(0));
970
967
 
971
968
before_err:
1018
1015
      }
1019
1016
    }
1020
1017
  }
1021
 
  return session->abortOnWarning() ? err : 0;
 
1018
  return session->abort_on_warning ? err : 0;
1022
1019
}
1023
1020
 
1024
1021
/***************************************************************************
1030
1027
  make insert specific preparation and checks after opening tables
1031
1028
 
1032
1029
  SYNOPSIS
1033
 
    insert_select_prepare()
 
1030
    mysql_insert_select_prepare()
1034
1031
    session         thread handler
1035
1032
 
1036
1033
  RETURN
1038
1035
    true  Error
1039
1036
*/
1040
1037
 
1041
 
bool insert_select_prepare(Session *session)
 
1038
bool mysql_insert_select_prepare(Session *session)
1042
1039
{
1043
 
  LEX *lex= session->getLex();
 
1040
  LEX *lex= session->lex;
1044
1041
  Select_Lex *select_lex= &lex->select_lex;
1045
1042
 
1046
1043
  /*
1048
1045
    clause if table is VIEW
1049
1046
  */
1050
1047
 
1051
 
  if (prepare_insert(session, lex->query_tables,
 
1048
  if (mysql_prepare_insert(session, lex->query_tables,
1052
1049
                           lex->query_tables->table, lex->field_list, 0,
1053
1050
                           lex->update_list, lex->value_list,
1054
1051
                           lex->duplicates,
1087
1084
int
1088
1085
select_insert::prepare(List<Item> &values, Select_Lex_Unit *u)
1089
1086
{
 
1087
  LEX *lex= session->lex;
1090
1088
  int res;
1091
1089
  table_map map= 0;
1092
 
  Select_Lex *lex_current_select_save= session->getLex()->current_select;
 
1090
  Select_Lex *lex_current_select_save= lex->current_select;
1093
1091
 
1094
1092
 
1095
1093
  unit= u;
1099
1097
    select, LEX::current_select should point to the first select while
1100
1098
    we are fixing fields from insert list.
1101
1099
  */
1102
 
  session->getLex()->current_select= &session->getLex()->select_lex;
 
1100
  lex->current_select= &lex->select_lex;
1103
1101
  res= check_insert_fields(session, table_list, *fields, values,
1104
1102
                           !insert_into_view, &map) ||
1105
1103
       setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0);
1106
1104
 
1107
1105
  if (!res && fields->elements)
1108
1106
  {
1109
 
    bool saved_abort_on_warning= session->abortOnWarning();
1110
 
    session->setAbortOnWarning(not info.ignore);
 
1107
    bool saved_abort_on_warning= session->abort_on_warning;
 
1108
    session->abort_on_warning= !info.ignore;
1111
1109
    res= check_that_all_fields_are_given_values(session, table_list->table,
1112
1110
                                                table_list);
1113
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1111
    session->abort_on_warning= saved_abort_on_warning;
1114
1112
  }
1115
1113
 
1116
1114
  if (info.handle_duplicates == DUP_UPDATE && !res)
1117
1115
  {
1118
 
    Name_resolution_context *context= &session->getLex()->select_lex.context;
 
1116
    Name_resolution_context *context= &lex->select_lex.context;
1119
1117
    Name_resolution_context_state ctx_state;
1120
1118
 
1121
1119
    /* Save the state of the current name resolution context. */
1133
1131
      We use next_name_resolution_table descructively, so check it first (views?)
1134
1132
    */
1135
1133
    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)
 
1134
    if (lex->select_lex.group_list.elements == 0 &&
 
1135
        !lex->select_lex.with_sum_func)
1138
1136
      /*
1139
1137
        We must make a single context out of the two separate name resolution contexts :
1140
1138
        the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
1153
1151
        order to get correct values from those fields when the select
1154
1152
        employs a temporary table.
1155
1153
      */
1156
 
      List<Item>::iterator li(info.update_values->begin());
 
1154
      List_iterator<Item> li(*info.update_values);
1157
1155
      Item *item;
1158
1156
 
1159
1157
      while ((item= li++))
1160
1158
      {
1161
1159
        item->transform(&Item::update_value_transformer,
1162
 
                        (unsigned char*)session->getLex()->current_select);
 
1160
                        (unsigned char*)lex->current_select);
1163
1161
      }
1164
1162
    }
1165
1163
 
1167
1165
    ctx_state.restore_state(context, table_list);
1168
1166
  }
1169
1167
 
1170
 
  session->getLex()->current_select= lex_current_select_save;
 
1168
  lex->current_select= lex_current_select_save;
1171
1169
  if (res)
1172
1170
    return(1);
1173
1171
  /*
1183
1181
  if (unique_table(table_list, table_list->next_global))
1184
1182
  {
1185
1183
    /* 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;
 
1184
    lex->current_select->options|= OPTION_BUFFER_RESULT;
 
1185
    lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1188
1186
  }
1189
 
  else if (not (session->getLex()->current_select->options & OPTION_BUFFER_RESULT))
 
1187
  else if (!(lex->current_select->options & OPTION_BUFFER_RESULT))
1190
1188
  {
1191
1189
    /*
1192
1190
      We must not yet prepare the result table if it is the same as one of the
1203
1201
  table->next_number_field=table->found_next_number_field;
1204
1202
 
1205
1203
  session->cuted_fields=0;
1206
 
 
1207
1204
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1208
1205
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1209
 
 
1210
1206
  if (info.handle_duplicates == DUP_REPLACE)
1211
1207
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1212
 
 
1213
1208
  if (info.handle_duplicates == DUP_UPDATE)
1214
1209
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1215
 
 
1216
 
  session->setAbortOnWarning(not info.ignore);
 
1210
  session->abort_on_warning= !info.ignore;
1217
1211
  table->mark_columns_needed_for_insert();
1218
1212
 
1219
1213
 
1239
1233
 
1240
1234
int select_insert::prepare2(void)
1241
1235
{
1242
 
  if (session->getLex()->current_select->options & OPTION_BUFFER_RESULT)
 
1236
 
 
1237
  if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1243
1238
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
1244
 
 
1245
1239
  return(0);
1246
1240
}
1247
1241
 
1262
1256
    table->cursor->ha_reset();
1263
1257
  }
1264
1258
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1265
 
  session->setAbortOnWarning(false);
 
1259
  session->abort_on_warning= 0;
1266
1260
  return;
1267
1261
}
1268
1262
 
1270
1264
bool select_insert::send_data(List<Item> &values)
1271
1265
{
1272
1266
 
1273
 
  bool error= false;
 
1267
  bool error=0;
1274
1268
 
1275
1269
  if (unit->offset_limit_cnt)
1276
1270
  {                                             // using limit offset,count
1277
1271
    unit->offset_limit_cnt--;
1278
 
    return false;
 
1272
    return(0);
1279
1273
  }
1280
1274
 
1281
1275
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1282
1276
  store_values(values);
1283
1277
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1284
1278
  if (session->is_error())
1285
 
    return true;
 
1279
  {
 
1280
    /*
 
1281
     * If we fail mid-way through INSERT..SELECT, we need to remove any
 
1282
     * records that we added to the current Statement message. We can
 
1283
     * use session->row_count to know how many records we have already added.
 
1284
     */
 
1285
    TransactionServices &ts= TransactionServices::singleton();
 
1286
    ts.removeStatementRecords(session, (session->row_count - 1));
 
1287
    return(1);
 
1288
  }
1286
1289
 
1287
1290
  // Release latches in case bulk insert takes a long time
1288
1291
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1332
1335
    fill_record(session, table->getFields(), values, true);
1333
1336
}
1334
1337
 
1335
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1338
void select_insert::send_error(uint32_t errcode,const char *err)
1336
1339
{
 
1340
 
 
1341
 
1337
1342
  my_message(errcode, err, MYF(0));
 
1343
 
 
1344
  return;
1338
1345
}
1339
1346
 
1340
1347
 
1383
1390
    (session->arg_of_last_insert_id_function ?
1384
1391
     session->first_successful_insert_id_in_prev_stmt :
1385
1392
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1386
 
  session->my_ok((ulong) session->rowCount(),
 
1393
  session->my_ok((ulong) session->row_count_func,
1387
1394
                 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());
 
1395
  session->status_var.inserted_row_count+= session->row_count_func; 
 
1396
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1390
1397
  return 0;
1391
1398
}
1392
1399
 
1488
1495
                                      List<Item> *items,
1489
1496
                                      bool is_if_not_exists,
1490
1497
                                      DrizzleLock **lock,
1491
 
                                      identifier::Table::const_reference identifier)
 
1498
                                      TableIdentifier &identifier)
1492
1499
{
1493
1500
  TableShare share(message::Table::INTERNAL);
1494
1501
  uint32_t select_field_count= items->elements;
1495
1502
  /* Add selected items to field list */
1496
 
  List<Item>::iterator it(items->begin());
 
1503
  List_iterator_fast<Item> it(*items);
1497
1504
  Item *item;
1498
1505
  Field *tmp_field;
 
1506
  bool not_used;
1499
1507
 
1500
1508
  if (not (identifier.isTmp()) && create_table->table->db_stat)
1501
1509
  {
1515
1523
 
1516
1524
  {
1517
1525
    table::Shell tmp_table(share);              // Used during 'CreateField()'
 
1526
    tmp_table.timestamp_field= 0;
 
1527
 
 
1528
    tmp_table.getMutableShare()->db_create_options= 0;
 
1529
    tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1518
1530
 
1519
1531
    if (not table_proto.engine().name().compare("MyISAM"))
1520
1532
      tmp_table.getMutableShare()->db_low_byte_first= true;
1521
1533
    else if (not table_proto.engine().name().compare("MEMORY"))
1522
1534
      tmp_table.getMutableShare()->db_low_byte_first= true;
1523
1535
 
 
1536
    tmp_table.null_row= false;
 
1537
    tmp_table.maybe_null= false;
 
1538
 
1524
1539
    tmp_table.in_use= session;
1525
1540
 
1526
1541
    while ((item=it++))
1571
1586
  */
1572
1587
  Table *table= 0;
1573
1588
  {
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))
 
1589
    if (not mysql_create_table_no_lock(session,
 
1590
                                       identifier,
 
1591
                                       create_info,
 
1592
                                       table_proto,
 
1593
                                       alter_info,
 
1594
                                       false,
 
1595
                                       select_field_count,
 
1596
                                       is_if_not_exists))
1582
1597
    {
1583
1598
      if (create_info->table_existed && not identifier.isTmp())
1584
1599
      {
1593
1608
 
1594
1609
      if (not identifier.isTmp())
1595
1610
      {
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());
 
1611
        LOCK_open.lock(); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1598
1612
 
1599
1613
        if (create_table->table)
1600
1614
        {
1602
1616
 
1603
1617
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1604
1618
          {
1605
 
            (void)plugin::StorageEngine::dropTable(*session, identifier);
 
1619
            quick_rm_table(*session, identifier);
1606
1620
          }
1607
1621
          else
1608
1622
          {
1611
1625
        }
1612
1626
        else
1613
1627
        {
1614
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
 
1628
          quick_rm_table(*session, identifier);
1615
1629
        }
 
1630
 
 
1631
        LOCK_open.unlock();
1616
1632
      }
1617
1633
      else
1618
1634
      {
1634
1650
  }
1635
1651
 
1636
1652
  table->reginfo.lock_type=TL_WRITE;
1637
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1653
  if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1638
1654
  {
1639
1655
    if (*lock)
1640
1656
    {
1644
1660
 
1645
1661
    if (not create_info->table_existed)
1646
1662
      session->drop_open_table(table, identifier);
1647
 
 
1648
1663
    return NULL;
1649
1664
  }
1650
1665
 
1700
1715
 
1701
1716
  /* Mark all fields that are given values */
1702
1717
  for (Field **f= field ; *f ; f++)
1703
 
  {
1704
 
    table->setWriteSet((*f)->position());
1705
 
  }
 
1718
    table->setWriteSet((*f)->field_index);
1706
1719
 
1707
1720
  /* Don't set timestamp if used */
1708
1721
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1712
1725
  session->cuted_fields=0;
1713
1726
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1714
1727
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1715
 
 
1716
1728
  if (info.handle_duplicates == DUP_REPLACE)
1717
1729
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1718
 
 
1719
1730
  if (info.handle_duplicates == DUP_UPDATE)
1720
1731
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1721
 
 
1722
1732
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1723
 
  session->setAbortOnWarning(not info.ignore);
 
1733
  session->abort_on_warning= !info.ignore;
1724
1734
  if (check_that_all_fields_are_given_values(session, table, table_list))
1725
1735
    return(1);
1726
 
 
1727
1736
  table->mark_columns_needed_for_insert();
1728
1737
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1729
1738
  return(0);
1735
1744
}
1736
1745
 
1737
1746
 
1738
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1747
void select_create::send_error(uint32_t errcode,const char *err)
1739
1748
{
1740
1749
  /*
1741
1750
    This will execute any rollbacks that are necessary before writing
1749
1758
 
1750
1759
  */
1751
1760
  select_insert::send_error(errcode, err);
 
1761
 
 
1762
  return;
1752
1763
}
1753
1764
 
1754
1765
 
1767
1778
    if (!table->getShare()->getType())
1768
1779
    {
1769
1780
      TransactionServices &transaction_services= TransactionServices::singleton();
1770
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1781
      transaction_services.autocommitOrRollback(session, 0);
1771
1782
      (void) session->endActiveTransaction();
1772
1783
    }
1773
1784