~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Monty Taylor
  • Date: 2009-09-22 23:50:12 UTC
  • mto: This revision was merged to the branch mainline in revision 1184.
  • Revision ID: mordred@inaugust.com-20090922235012-i0a3bs91f6krqduc
Fixed multi_malloc.h include guard.
Added include guard checking script.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Insert of records */
18
18
 
19
 
#include "config.h"
20
 
#include <cstdio>
 
19
#include <drizzled/server_includes.h>
21
20
#include <drizzled/sql_select.h>
22
21
#include <drizzled/show.h>
23
22
#include <drizzled/error.h>
27
26
#include <drizzled/sql_load.h>
28
27
#include <drizzled/field/timestamp.h>
29
28
#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
 
 
35
 
#include "drizzled/table/shell.h"
36
 
 
37
 
namespace drizzled
38
 
{
39
 
 
40
 
extern plugin::StorageEngine *heap_engine;
41
 
extern plugin::StorageEngine *myisam_engine;
 
29
 
 
30
using namespace drizzled;
42
31
 
43
32
/*
44
33
  Check if insert fields are correct.
70
59
 
71
60
  if (fields.elements == 0 && values.elements != 0)
72
61
  {
73
 
    if (values.elements != table->getShare()->sizeFields())
 
62
    if (values.elements != table->s->fields)
74
63
    {
75
64
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
76
65
      return -1;
123
112
    if (table->timestamp_field) // Don't automaticly set timestamp if used
124
113
    {
125
114
      if (table->timestamp_field->isWriteSet())
126
 
      {
127
115
        clear_timestamp_auto_bits(table->timestamp_field_type,
128
116
                                  TIMESTAMP_AUTO_SET_ON_INSERT);
129
 
      }
130
117
      else
131
118
      {
132
 
        table->setWriteSet(table->timestamp_field->position());
 
119
        table->setWriteSet(table->timestamp_field->field_index);
133
120
      }
134
121
    }
135
122
  }
170
157
      Unmark the timestamp field so that we can check if this is modified
171
158
      by update_fields
172
159
    */
173
 
    timestamp_mark= table->write_set->test(table->timestamp_field->position());
174
 
    table->write_set->reset(table->timestamp_field->position());
 
160
    timestamp_mark= table->write_set->testAndClear(table->timestamp_field->field_index);
175
161
  }
176
162
 
177
163
  /* Check the fields we are going to modify */
182
168
  {
183
169
    /* Don't set timestamp column if this is modified. */
184
170
    if (table->timestamp_field->isWriteSet())
185
 
    {
186
171
      clear_timestamp_auto_bits(table->timestamp_field_type,
187
172
                                TIMESTAMP_AUTO_SET_ON_UPDATE);
188
 
    }
189
 
 
190
173
    if (timestamp_mark)
191
 
    {
192
 
      table->setWriteSet(table->timestamp_field->position());
193
 
    }
 
174
      table->setWriteSet(table->timestamp_field->field_index);
194
175
  }
195
176
  return 0;
196
177
}
241
222
  uint32_t value_count;
242
223
  ulong counter = 1;
243
224
  uint64_t id;
244
 
  CopyInfo info;
 
225
  COPY_INFO info;
245
226
  Table *table= 0;
246
227
  List_iterator_fast<List_item> its(values_list);
247
228
  List_item *values;
259
240
                    values_list.elements > 1);
260
241
 
261
242
  if (session->openTablesLock(table_list))
262
 
  {
263
 
    DRIZZLE_INSERT_DONE(1, 0);
264
243
    return true;
265
 
  }
266
244
 
267
245
  lock_type= table_list->lock_type;
268
246
 
276
254
                           false,
277
255
                           (fields.elements || !value_count ||
278
256
                            (0) != 0), !ignore))
279
 
  {
280
 
    if (table != NULL)
281
 
      table->cursor->ha_release_auto_increment();
282
 
    if (!joins_freed)
283
 
      free_underlaid_joins(session, &session->lex->select_lex);
284
 
    session->abort_on_warning= 0;
285
 
    DRIZZLE_INSERT_DONE(1, 0);
286
 
    return true;
287
 
  }
 
257
    goto abort;
288
258
 
289
259
  /* mysql_prepare_insert set table_list->table if it was not set */
290
260
  table= table_list->table;
315
285
    if (values->elements != value_count)
316
286
    {
317
287
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
318
 
 
319
 
      if (table != NULL)
320
 
        table->cursor->ha_release_auto_increment();
321
 
      if (!joins_freed)
322
 
        free_underlaid_joins(session, &session->lex->select_lex);
323
 
      session->abort_on_warning= 0;
324
 
      DRIZZLE_INSERT_DONE(1, 0);
325
 
 
326
 
      return true;
 
288
      goto abort;
327
289
    }
328
290
    if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
329
 
    {
330
 
      if (table != NULL)
331
 
        table->cursor->ha_release_auto_increment();
332
 
      if (!joins_freed)
333
 
        free_underlaid_joins(session, &session->lex->select_lex);
334
 
      session->abort_on_warning= 0;
335
 
      DRIZZLE_INSERT_DONE(1, 0);
336
 
      return true;
337
 
    }
 
291
      goto abort;
338
292
  }
339
293
  its.rewind ();
340
294
 
342
296
  ctx_state.restore_state(context, table_list);
343
297
 
344
298
  /*
345
 
    Fill in the given fields and dump it to the table cursor
 
299
    Fill in the given fields and dump it to the table file
346
300
  */
 
301
  memset(&info, 0, sizeof(info));
347
302
  info.ignore= ignore;
348
303
  info.handle_duplicates=duplic;
349
304
  info.update_fields= &update_fields;
354
309
    For single line insert, generate an error if try to set a NOT NULL field
355
310
    to NULL.
356
311
  */
357
 
  session->count_cuted_fields= ignore ? CHECK_FIELD_WARN : CHECK_FIELD_ERROR_FOR_NULL;
358
 
 
 
312
  session->count_cuted_fields= ((values_list.elements == 1 &&
 
313
                             !ignore) ?
 
314
                            CHECK_FIELD_ERROR_FOR_NULL :
 
315
                            CHECK_FIELD_WARN);
359
316
  session->cuted_fields = 0L;
360
317
  table->next_number_field=table->found_next_number_field;
361
318
 
362
319
  error=0;
363
320
  session->set_proc_info("update");
364
321
  if (duplic == DUP_REPLACE)
365
 
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
 
322
    table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
366
323
  if (duplic == DUP_UPDATE)
367
 
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
 
324
    table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
368
325
  {
369
326
    if (duplic != DUP_ERROR || ignore)
370
 
      table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
371
 
    table->cursor->ha_start_bulk_insert(values_list.elements);
 
327
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
328
    table->file->ha_start_bulk_insert(values_list.elements);
372
329
  }
373
330
 
374
331
 
381
338
    if (fields.elements || !value_count)
382
339
    {
383
340
      table->restoreRecordAsDefault();  // Get empty record
384
 
      if (fill_record(session, fields, *values))
 
341
      if (fill_record(session, fields, *values, 0))
385
342
      {
386
343
        if (values_list.elements != 1 && ! session->is_error())
387
344
        {
399
356
    }
400
357
    else
401
358
    {
402
 
      table->restoreRecordAsDefault();  // Get empty record
403
 
 
404
 
      if (fill_record(session, table->getFields(), *values))
 
359
      if (session->used_tables)                 // Column used in values()
 
360
        table->restoreRecordAsDefault();        // Get empty record
 
361
      else
 
362
      {
 
363
        /*
 
364
          Fix delete marker. No need to restore rest of record since it will
 
365
          be overwritten by fill_record() anyway (and fill_record() does not
 
366
          use default values in this case).
 
367
        */
 
368
        table->record[0][0]= table->s->default_values[0];
 
369
      }
 
370
      if (fill_record(session, table->field, *values, 0))
405
371
      {
406
372
        if (values_list.elements != 1 && ! session->is_error())
407
373
        {
414
380
    }
415
381
 
416
382
    // Release latches in case bulk insert takes a long time
417
 
    plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
383
    ha_release_temporary_latches(session);
418
384
 
419
385
    error=write_record(session, table ,&info);
420
386
    if (error)
434
400
      Do not do this release if this is a delayed insert, it would steal
435
401
      auto_inc values from the delayed_insert thread as they share Table.
436
402
    */
437
 
    table->cursor->ha_release_auto_increment();
438
 
    if (table->cursor->ha_end_bulk_insert() && !error)
 
403
    table->file->ha_release_auto_increment();
 
404
    if (table->file->ha_end_bulk_insert() && !error)
439
405
    {
440
 
      table->print_error(errno,MYF(0));
 
406
      table->file->print_error(my_errno,MYF(0));
441
407
      error=1;
442
408
    }
443
409
    if (duplic != DUP_ERROR || ignore)
444
 
      table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
410
      table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
445
411
 
446
 
    transactional_table= table->cursor->has_transactions();
 
412
    transactional_table= table->file->has_transactions();
447
413
 
448
414
    changed= (info.copied || info.deleted || info.updated);
449
 
    if ((changed && error <= 0) || session->transaction.stmt.hasModifiedNonTransData())
 
415
    if ((changed && error <= 0) || session->transaction.stmt.modified_non_trans_table)
450
416
    {
451
 
      if (session->transaction.stmt.hasModifiedNonTransData())
452
 
        session->transaction.all.markModifiedNonTransData();
 
417
      if (session->transaction.stmt.modified_non_trans_table)
 
418
        session->transaction.all.modified_non_trans_table= true;
453
419
    }
454
 
    assert(transactional_table || !changed || session->transaction.stmt.hasModifiedNonTransData());
 
420
    assert(transactional_table || !changed || session->transaction.stmt.modified_non_trans_table);
455
421
 
456
422
  }
457
423
  session->set_proc_info("end");
475
441
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
476
442
  table->auto_increment_field_not_null= false;
477
443
  if (duplic == DUP_REPLACE)
478
 
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
444
    table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
479
445
 
480
446
  if (error)
481
 
  {
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;
489
 
  }
490
 
 
 
447
    goto abort;
491
448
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
492
449
                                    !session->cuted_fields))
493
450
  {
499
456
  {
500
457
    char buff[160];
501
458
    if (ignore)
502
 
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
459
      sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
503
460
              (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
504
461
    else
505
 
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
462
      sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
506
463
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
507
464
    session->row_count_func= info.copied + info.deleted + info.updated;
508
465
    session->my_ok((ulong) session->row_count_func,
509
466
                   info.copied + info.deleted + info.touched, id, buff);
510
467
  }
511
 
  session->status_var.inserted_row_count+= session->row_count_func;
512
468
  session->abort_on_warning= 0;
513
 
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
 
469
  DRIZZLE_INSERT_END();
 
470
  return(false);
514
471
 
515
 
  return false;
 
472
abort:
 
473
  if (table != NULL)
 
474
    table->file->ha_release_auto_increment();
 
475
  if (!joins_freed)
 
476
    free_underlaid_joins(session, &session->lex->select_lex);
 
477
  session->abort_on_warning= 0;
 
478
  DRIZZLE_INSERT_END();
 
479
  return(true);
516
480
}
517
481
 
518
482
 
688
652
  if (!select_insert)
689
653
  {
690
654
    TableList *duplicate;
691
 
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
 
655
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 1)))
692
656
    {
693
657
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
694
658
 
706
670
 
707
671
static int last_uniq_key(Table *table,uint32_t keynr)
708
672
{
709
 
  while (++keynr < table->getShare()->sizeKeys())
 
673
  while (++keynr < table->s->keys)
710
674
    if (table->key_info[keynr].flags & HA_NOSAME)
711
675
      return 0;
712
676
  return 1;
721
685
     write_record()
722
686
      session   - thread context
723
687
      table - table to which record should be written
724
 
      info  - CopyInfo structure describing handling of duplicates
 
688
      info  - COPY_INFO structure describing handling of duplicates
725
689
              and which is used for counting number of records inserted
726
690
              and deleted.
727
691
 
731
695
    then both on update triggers will work instead. Similarly both on
732
696
    delete triggers will be invoked if we will delete conflicting records.
733
697
 
734
 
    Sets session->transaction.stmt.modified_non_trans_data to true if table which is updated didn't have
 
698
    Sets session->transaction.stmt.modified_non_trans_table to true if table which is updated didn't have
735
699
    transactions.
736
700
 
737
701
  RETURN VALUE
740
704
*/
741
705
 
742
706
 
743
 
int write_record(Session *session, Table *table,CopyInfo *info)
 
707
int write_record(Session *session, Table *table,COPY_INFO *info)
744
708
{
745
709
  int error;
746
 
  std::vector<unsigned char> key;
747
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
748
 
  uint64_t prev_insert_id= table->cursor->next_insert_id;
 
710
  char *key=0;
 
711
  MyBitmap *save_read_set, *save_write_set;
 
712
  uint64_t prev_insert_id= table->file->next_insert_id;
749
713
  uint64_t insert_id_for_cur_row= 0;
750
714
 
751
715
 
755
719
 
756
720
  if (info->handle_duplicates == DUP_REPLACE || info->handle_duplicates == DUP_UPDATE)
757
721
  {
758
 
    while ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
722
    while ((error=table->file->ha_write_row(table->record[0])))
759
723
    {
760
724
      uint32_t key_nr;
761
725
      /*
765
729
        the autogenerated value to avoid session->insert_id_for_cur_row to become
766
730
        0.
767
731
      */
768
 
      if (table->cursor->insert_id_for_cur_row > 0)
769
 
        insert_id_for_cur_row= table->cursor->insert_id_for_cur_row;
 
732
      if (table->file->insert_id_for_cur_row > 0)
 
733
        insert_id_for_cur_row= table->file->insert_id_for_cur_row;
770
734
      else
771
 
        table->cursor->insert_id_for_cur_row= insert_id_for_cur_row;
 
735
        table->file->insert_id_for_cur_row= insert_id_for_cur_row;
772
736
      bool is_duplicate_key_error;
773
 
      if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
737
      if (table->file->is_fatal_error(error, HA_CHECK_DUP))
774
738
        goto err;
775
 
      is_duplicate_key_error= table->cursor->is_fatal_error(error, 0);
 
739
      is_duplicate_key_error= table->file->is_fatal_error(error, 0);
776
740
      if (!is_duplicate_key_error)
777
741
      {
778
742
        /*
784
748
          goto gok_or_after_err; /* Ignoring a not fatal error, return 0 */
785
749
        goto err;
786
750
      }
787
 
      if ((int) (key_nr = table->get_dup_key(error)) < 0)
 
751
      if ((int) (key_nr = table->file->get_dup_key(error)) < 0)
788
752
      {
789
753
        error= HA_ERR_FOUND_DUPP_KEY;         /* Database can't find key */
790
754
        goto err;
798
762
      */
799
763
      if (info->handle_duplicates == DUP_REPLACE &&
800
764
          table->next_number_field &&
801
 
          key_nr == table->getShare()->next_number_index &&
 
765
          key_nr == table->s->next_number_index &&
802
766
          (insert_id_for_cur_row > 0))
803
767
        goto err;
804
 
      if (table->cursor->getEngine()->check_flag(HTON_BIT_DUPLICATE_POS))
 
768
      if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
805
769
      {
806
 
        if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
770
        if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
807
771
          goto err;
808
772
      }
809
773
      else
810
774
      {
811
 
        if (table->cursor->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */
 
775
        if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */
812
776
        {
813
 
          error=errno;
 
777
          error=my_errno;
814
778
          goto err;
815
779
        }
816
780
 
817
 
        if (not key.size())
 
781
        if (!key)
818
782
        {
819
 
          key.resize(table->getShare()->max_unique_length);
 
783
          if (!(key=(char*) malloc(table->s->max_unique_length)))
 
784
          {
 
785
            error=ENOMEM;
 
786
            goto err;
 
787
          }
820
788
        }
821
 
        key_copy(&key[0], table->getInsertRecord(), table->key_info+key_nr, 0);
822
 
        if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
823
 
                                                    &key[0], HA_WHOLE_KEY,
 
789
        key_copy((unsigned char*) key,table->record[0],table->key_info+key_nr,0);
 
790
        if ((error=(table->file->index_read_idx_map(table->record[1],key_nr,
 
791
                                                    (unsigned char*) key, HA_WHOLE_KEY,
824
792
                                                    HA_READ_KEY_EXACT))))
825
793
          goto err;
826
794
      }
831
799
          that matches, is updated. If update causes a conflict again,
832
800
          an error is returned
833
801
        */
834
 
        assert(table->insert_values.size());
 
802
        assert(table->insert_values != NULL);
835
803
        table->storeRecordAsInsert();
836
804
        table->restoreRecord();
837
805
        assert(info->update_fields->elements ==
841
809
                                                 info->ignore))
842
810
          goto before_err;
843
811
 
844
 
        table->cursor->restore_auto_increment(prev_insert_id);
 
812
        table->file->restore_auto_increment(prev_insert_id);
845
813
        if (table->next_number_field)
846
 
          table->cursor->adjust_next_insert_id_after_explicit_value(
 
814
          table->file->adjust_next_insert_id_after_explicit_value(
847
815
            table->next_number_field->val_int());
848
816
        info->touched++;
849
 
 
850
 
        if (! table->records_are_comparable() || table->compare_records())
 
817
        if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
 
818
             !bitmap_is_subset(table->write_set, table->read_set)) ||
 
819
            table->compare_record())
851
820
        {
852
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
853
 
                                                table->getInsertRecord())) &&
 
821
          if ((error=table->file->ha_update_row(table->record[1],
 
822
                                                table->record[0])) &&
854
823
              error != HA_ERR_RECORD_IS_THE_SAME)
855
824
          {
856
825
            if (info->ignore &&
857
 
                !table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
826
                !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
858
827
            {
859
828
              goto gok_or_after_err;
860
829
            }
872
841
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
873
842
            handled separately by Session::arg_of_last_insert_id_function.
874
843
          */
875
 
          insert_id_for_cur_row= table->cursor->insert_id_for_cur_row= 0;
 
844
          insert_id_for_cur_row= table->file->insert_id_for_cur_row= 0;
876
845
          info->copied++;
877
846
        }
878
847
 
879
848
        if (table->next_number_field)
880
 
          table->cursor->adjust_next_insert_id_after_explicit_value(
 
849
          table->file->adjust_next_insert_id_after_explicit_value(
881
850
            table->next_number_field->val_int());
882
851
        info->touched++;
883
852
 
900
869
          ON UPDATE triggers.
901
870
        */
902
871
        if (last_uniq_key(table,key_nr) &&
903
 
            !table->cursor->referenced_by_foreign_key() &&
 
872
            !table->file->referenced_by_foreign_key() &&
904
873
            (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
905
874
             table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
906
875
        {
907
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
908
 
                                                table->getInsertRecord())) &&
 
876
          if ((error=table->file->ha_update_row(table->record[1],
 
877
                                                table->record[0])) &&
909
878
              error != HA_ERR_RECORD_IS_THE_SAME)
910
879
            goto err;
911
880
          if (error != HA_ERR_RECORD_IS_THE_SAME)
912
881
            info->deleted++;
913
882
          else
914
883
            error= 0;
915
 
          session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
 
884
          session->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
916
885
          /*
917
886
            Since we pretend that we have done insert we should call
918
887
            its after triggers.
921
890
        }
922
891
        else
923
892
        {
924
 
          if ((error=table->cursor->deleteRecord(table->getUpdateRecord())))
 
893
          if ((error=table->file->ha_delete_row(table->record[1])))
925
894
            goto err;
926
895
          info->deleted++;
927
 
          if (!table->cursor->has_transactions())
928
 
            session->transaction.stmt.markModifiedNonTransData();
 
896
          if (!table->file->has_transactions())
 
897
            session->transaction.stmt.modified_non_trans_table= true;
929
898
          /* Let us attempt do write_row() once more */
930
899
        }
931
900
      }
932
901
    }
933
 
    session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
 
902
    session->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
934
903
    /*
935
904
      Restore column maps if they where replaced during an duplicate key
936
905
      problem.
937
906
    */
938
907
    if (table->read_set != save_read_set ||
939
908
        table->write_set != save_write_set)
940
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
909
      table->column_bitmaps_set(save_read_set, save_write_set);
941
910
  }
942
 
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
911
  else if ((error=table->file->ha_write_row(table->record[0])))
943
912
  {
944
913
    if (!info->ignore ||
945
 
        table->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
914
        table->file->is_fatal_error(error, HA_CHECK_DUP))
946
915
      goto err;
947
 
    table->cursor->restore_auto_increment(prev_insert_id);
 
916
    table->file->restore_auto_increment(prev_insert_id);
948
917
    goto gok_or_after_err;
949
918
  }
950
919
 
951
920
after_n_copied_inc:
952
921
  info->copied++;
953
 
  session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
 
922
  session->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row);
954
923
 
955
924
gok_or_after_err:
956
 
  if (!table->cursor->has_transactions())
957
 
    session->transaction.stmt.markModifiedNonTransData();
 
925
  if (key)
 
926
    free(key);
 
927
  if (!table->file->has_transactions())
 
928
    session->transaction.stmt.modified_non_trans_table= true;
958
929
  return(0);
959
930
 
960
931
err:
962
933
  /* current_select is NULL if this is a delayed insert */
963
934
  if (session->lex->current_select)
964
935
    session->lex->current_select->no_error= 0;        // Give error
965
 
  table->print_error(error,MYF(0));
 
936
  table->file->print_error(error,MYF(0));
966
937
 
967
938
before_err:
968
 
  table->cursor->restore_auto_increment(prev_insert_id);
969
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
970
 
  return 1;
 
939
  table->file->restore_auto_increment(prev_insert_id);
 
940
  if (key)
 
941
    free(key);
 
942
  table->column_bitmaps_set(save_read_set, save_write_set);
 
943
  return(1);
971
944
}
972
945
 
973
946
 
980
953
{
981
954
  int err= 0;
982
955
 
983
 
  for (Field **field=entry->getFields() ; *field ; field++)
 
956
  for (Field **field=entry->field ; *field ; field++)
984
957
  {
985
958
    if (((*field)->isWriteSet()) == false)
986
959
    {
1068
1041
                             List<Item> *update_fields,
1069
1042
                             List<Item> *update_values,
1070
1043
                             enum_duplicates duplic,
1071
 
                             bool ignore_check_option_errors) :
1072
 
  table_list(table_list_par), table(table_par), fields(fields_par),
1073
 
  autoinc_value_of_last_inserted_row(0),
1074
 
  insert_into_view(table_list_par && 0 != 0)
 
1044
                             bool ignore_check_option_errors)
 
1045
  :table_list(table_list_par), table(table_par), fields(fields_par),
 
1046
   autoinc_value_of_last_inserted_row(0),
 
1047
   insert_into_view(table_list_par && 0 != 0)
1075
1048
{
 
1049
  memset(&info, 0, sizeof(info));
1076
1050
  info.handle_duplicates= duplic;
1077
1051
  info.ignore= ignore_check_option_errors;
1078
1052
  info.update_fields= update_fields;
1177
1151
    Is table which we are changing used somewhere in other parts of
1178
1152
    query
1179
1153
  */
1180
 
  if (unique_table(table_list, table_list->next_global))
 
1154
  if (unique_table(session, table_list, table_list->next_global, 0))
1181
1155
  {
1182
1156
    /* Using same table for INSERT and SELECT */
1183
1157
    lex->current_select->options|= OPTION_BUFFER_RESULT;
1194
1168
      We won't start bulk inserts at all if this statement uses functions or
1195
1169
      should invoke triggers since they may access to the same table too.
1196
1170
    */
1197
 
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
 
1171
    table->file->ha_start_bulk_insert((ha_rows) 0);
1198
1172
  }
1199
1173
  table->restoreRecordAsDefault();              // Get empty record
1200
1174
  table->next_number_field=table->found_next_number_field;
1201
1175
 
1202
1176
  session->cuted_fields=0;
1203
1177
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1204
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
1178
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1205
1179
  if (info.handle_duplicates == DUP_REPLACE)
1206
 
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
 
1180
    table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1207
1181
  if (info.handle_duplicates == DUP_UPDATE)
1208
 
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
 
1182
    table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1209
1183
  session->abort_on_warning= !info.ignore;
1210
1184
  table->mark_columns_needed_for_insert();
1211
1185
 
1234
1208
{
1235
1209
 
1236
1210
  if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1237
 
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
 
1211
    table->file->ha_start_bulk_insert((ha_rows) 0);
1238
1212
  return(0);
1239
1213
}
1240
1214
 
1252
1226
  {
1253
1227
    table->next_number_field=0;
1254
1228
    table->auto_increment_field_not_null= false;
1255
 
    table->cursor->ha_reset();
 
1229
    table->file->ha_reset();
1256
1230
  }
1257
1231
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1258
1232
  session->abort_on_warning= 0;
1278
1252
    return(1);
1279
1253
 
1280
1254
  // Release latches in case bulk insert takes a long time
1281
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1255
  ha_release_temporary_latches(session);
1282
1256
 
1283
1257
  error= write_record(session, table, &info);
1284
 
  table->auto_increment_field_not_null= false;
1285
1258
 
1286
1259
  if (!error)
1287
1260
  {
1320
1293
void select_insert::store_values(List<Item> &values)
1321
1294
{
1322
1295
  if (fields->elements)
1323
 
    fill_record(session, *fields, values, true);
 
1296
    fill_record(session, *fields, values, 1);
1324
1297
  else
1325
 
    fill_record(session, table->getFields(), values, true);
 
1298
    fill_record(session, table->field, values, 1);
1326
1299
}
1327
1300
 
1328
1301
void select_insert::send_error(uint32_t errcode,const char *err)
1338
1311
bool select_insert::send_eof()
1339
1312
{
1340
1313
  int error;
1341
 
  bool const trans_table= table->cursor->has_transactions();
 
1314
  bool const trans_table= table->file->has_transactions();
1342
1315
  uint64_t id;
1343
1316
  bool changed;
1344
1317
 
1345
 
  error= table->cursor->ha_end_bulk_insert();
1346
 
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1347
 
  table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
1318
  error= table->file->ha_end_bulk_insert();
 
1319
  table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
1320
  table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1348
1321
 
1349
1322
  if ((changed= (info.copied || info.deleted || info.updated)))
1350
1323
  {
1351
1324
    /*
1352
1325
      We must invalidate the table in the query cache before binlog writing
1353
 
      and autocommitOrRollback.
 
1326
      and ha_autocommit_or_rollback.
1354
1327
    */
1355
 
    if (session->transaction.stmt.hasModifiedNonTransData())
1356
 
      session->transaction.all.markModifiedNonTransData();
 
1328
    if (session->transaction.stmt.modified_non_trans_table)
 
1329
      session->transaction.all.modified_non_trans_table= true;
1357
1330
  }
1358
1331
  assert(trans_table || !changed ||
1359
 
              session->transaction.stmt.hasModifiedNonTransData());
 
1332
              session->transaction.stmt.modified_non_trans_table);
1360
1333
 
1361
 
  table->cursor->ha_release_auto_increment();
 
1334
  table->file->ha_release_auto_increment();
1362
1335
 
1363
1336
  if (error)
1364
1337
  {
1365
 
    table->print_error(error,MYF(0));
1366
 
    DRIZZLE_INSERT_SELECT_DONE(error, 0);
1367
 
    return 1;
 
1338
    table->file->print_error(error,MYF(0));
 
1339
    return(1);
1368
1340
  }
1369
1341
  char buff[160];
1370
1342
  if (info.ignore)
1371
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1343
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1372
1344
            (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
1373
1345
  else
1374
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1346
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1375
1347
            (ulong) (info.deleted+info.updated), (ulong) session->cuted_fields);
1376
1348
  session->row_count_func= info.copied + info.deleted + info.updated;
1377
1349
 
1382
1354
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1383
1355
  session->my_ok((ulong) session->row_count_func,
1384
1356
                 info.copied + info.deleted + info.touched, id, buff);
1385
 
  session->status_var.inserted_row_count+= session->row_count_func; 
1386
 
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1387
 
  return 0;
 
1357
  return(0);
1388
1358
}
1389
1359
 
1390
1360
void select_insert::abort() {
1400
1370
  {
1401
1371
    bool changed, transactional_table;
1402
1372
 
1403
 
    table->cursor->ha_end_bulk_insert();
 
1373
    table->file->ha_end_bulk_insert();
1404
1374
 
1405
1375
    /*
1406
1376
      If at least one row has been inserted/modified and will stay in
1417
1387
      zero, so no check for that is made.
1418
1388
    */
1419
1389
    changed= (info.copied || info.deleted || info.updated);
1420
 
    transactional_table= table->cursor->has_transactions();
 
1390
    transactional_table= table->file->has_transactions();
1421
1391
    assert(transactional_table || !changed ||
1422
 
                session->transaction.stmt.hasModifiedNonTransData());
1423
 
    table->cursor->ha_release_auto_increment();
1424
 
  }
1425
 
 
1426
 
  if (DRIZZLE_INSERT_SELECT_DONE_ENABLED())
1427
 
  {
1428
 
    DRIZZLE_INSERT_SELECT_DONE(0, info.copied + info.deleted + info.updated);
 
1392
                session->transaction.stmt.modified_non_trans_table);
 
1393
    table->file->ha_release_auto_increment();
1429
1394
  }
1430
1395
 
1431
1396
  return;
1452
1417
      items        in     List of items which should be used to produce rest
1453
1418
                          of fields for the table (corresponding fields will
1454
1419
                          be added to the end of alter_info->create_list)
1455
 
      lock         out    Pointer to the DrizzleLock object for table created
 
1420
      lock         out    Pointer to the DRIZZLE_LOCK object for table created
1456
1421
                          (or open temporary table) will be returned in this
1457
1422
                          parameter. Since this table is not included in
1458
1423
                          Session::lock caller is responsible for explicitly
1480
1445
 
1481
1446
static Table *create_table_from_items(Session *session, HA_CREATE_INFO *create_info,
1482
1447
                                      TableList *create_table,
1483
 
                                      message::Table &table_proto,
 
1448
                                      message::Table *table_proto,
1484
1449
                                      AlterInfo *alter_info,
1485
1450
                                      List<Item> *items,
1486
 
                                      bool is_if_not_exists,
1487
 
                                      DrizzleLock **lock,
1488
 
                                      TableIdentifier &identifier)
 
1451
                                      DRIZZLE_LOCK **lock)
1489
1452
{
1490
 
  TableShare share(message::Table::INTERNAL);
 
1453
  Table tmp_table;              // Used during 'CreateField()'
 
1454
  TableShare share;
 
1455
  Table *table= 0;
1491
1456
  uint32_t select_field_count= items->elements;
1492
1457
  /* Add selected items to field list */
1493
1458
  List_iterator_fast<Item> it(*items);
1495
1460
  Field *tmp_field;
1496
1461
  bool not_used;
1497
1462
 
1498
 
  if (not (identifier.isTmp()) && create_table->table->db_stat)
 
1463
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
 
1464
      create_table->table->db_stat)
1499
1465
  {
1500
1466
    /* Table already exists and was open at openTablesLock() stage. */
1501
 
    if (is_if_not_exists)
 
1467
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1502
1468
    {
1503
1469
      create_info->table_existed= 1;            // Mark that table existed
1504
1470
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1505
1471
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1506
 
                          create_table->getTableName());
 
1472
                          create_table->table_name);
1507
1473
      return create_table->table;
1508
1474
    }
1509
1475
 
1510
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1476
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1511
1477
    return NULL;
1512
1478
  }
1513
1479
 
 
1480
  tmp_table.alias= 0;
 
1481
  tmp_table.timestamp_field= 0;
 
1482
  tmp_table.s= &share;
 
1483
 
 
1484
  tmp_table.s->db_create_options=0;
 
1485
  tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1486
  tmp_table.s->db_low_byte_first=
 
1487
        test(create_info->db_type == myisam_engine ||
 
1488
             create_info->db_type == heap_engine);
 
1489
  tmp_table.null_row= false;
 
1490
  tmp_table.maybe_null= false;
 
1491
 
 
1492
  while ((item=it++))
1514
1493
  {
1515
 
    table::Shell tmp_table(share);              // Used during 'CreateField()'
1516
 
    tmp_table.timestamp_field= 0;
1517
 
 
1518
 
    tmp_table.getMutableShare()->db_create_options= 0;
1519
 
    tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1520
 
 
1521
 
    if (not table_proto.engine().name().compare("MyISAM"))
1522
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1523
 
    else if (not table_proto.engine().name().compare("MEMORY"))
1524
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1525
 
 
1526
 
    tmp_table.null_row= false;
1527
 
    tmp_table.maybe_null= false;
1528
 
 
1529
 
    tmp_table.in_use= session;
1530
 
 
1531
 
    while ((item=it++))
1532
 
    {
1533
 
      CreateField *cr_field;
1534
 
      Field *field, *def_field;
1535
 
      if (item->type() == Item::FUNC_ITEM)
1536
 
      {
1537
 
        if (item->result_type() != STRING_RESULT)
1538
 
        {
1539
 
          field= item->tmp_table_field(&tmp_table);
1540
 
        }
1541
 
        else
1542
 
        {
1543
 
          field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1544
 
        }
1545
 
      }
 
1494
    CreateField *cr_field;
 
1495
    Field *field, *def_field;
 
1496
    if (item->type() == Item::FUNC_ITEM)
 
1497
      if (item->result_type() != STRING_RESULT)
 
1498
        field= item->tmp_table_field(&tmp_table);
1546
1499
      else
1547
 
      {
1548
 
        field= create_tmp_field(session, &tmp_table, item, item->type(),
1549
 
                                (Item ***) 0, &tmp_field, &def_field, false,
1550
 
                                false, false, 0);
1551
 
      }
1552
 
 
1553
 
      if (!field ||
1554
 
          !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1555
 
                                            ((Item_field *)item)->field :
1556
 
                                            (Field*) 0))))
1557
 
      {
1558
 
        return NULL;
1559
 
      }
1560
 
 
1561
 
      if (item->maybe_null)
1562
 
      {
1563
 
        cr_field->flags &= ~NOT_NULL_FLAG;
1564
 
      }
1565
 
 
1566
 
      alter_info->create_list.push_back(cr_field);
1567
 
    }
 
1500
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1501
    else
 
1502
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1503
                              (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
 
1504
                              0);
 
1505
    if (!field ||
 
1506
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1507
                                           ((Item_field *)item)->field :
 
1508
                                           (Field*) 0))))
 
1509
      return NULL;
 
1510
    if (item->maybe_null)
 
1511
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1512
    alter_info->create_list.push_back(cr_field);
1568
1513
  }
1569
1514
 
1570
1515
  /*
1574
1519
    creating base table on which name we have exclusive lock. So code below
1575
1520
    should not cause deadlocks or races.
1576
1521
  */
1577
 
  Table *table= 0;
1578
1522
  {
1579
 
    if (not mysql_create_table_no_lock(session,
1580
 
                                       identifier,
1581
 
                                       create_info,
1582
 
                                       table_proto,
1583
 
                                       alter_info,
1584
 
                                       false,
1585
 
                                       select_field_count,
1586
 
                                       is_if_not_exists))
 
1523
    if (!mysql_create_table_no_lock(session, create_table->db,
 
1524
                                    create_table->table_name,
 
1525
                                    create_info,
 
1526
                                    table_proto,
 
1527
                                    alter_info, false,
 
1528
                                    select_field_count))
1587
1529
    {
1588
 
      if (create_info->table_existed && not identifier.isTmp())
 
1530
      if (create_info->table_existed &&
 
1531
          !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1589
1532
      {
1590
1533
        /*
1591
1534
          This means that someone created table underneath server
1592
1535
          or it was created via different mysqld front-end to the
1593
1536
          cluster. We don't have much options but throw an error.
1594
1537
        */
1595
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1538
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1596
1539
        return NULL;
1597
1540
      }
1598
1541
 
1599
 
      if (not identifier.isTmp())
 
1542
      if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1600
1543
      {
1601
 
        /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1602
 
        boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1603
 
 
1604
 
        if (create_table->table)
 
1544
        pthread_mutex_lock(&LOCK_open); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1545
        if (session->reopen_name_locked_table(create_table, false))
1605
1546
        {
1606
 
          table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1607
 
 
1608
 
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1609
 
          {
1610
 
            plugin::StorageEngine::dropTable(*session, identifier);
1611
 
          }
1612
 
          else
1613
 
          {
1614
 
            table= create_table->table;
1615
 
          }
 
1547
          quick_rm_table(create_info->db_type, create_table->db,
 
1548
                         create_table->table_name, false);
1616
1549
        }
1617
1550
        else
1618
 
        {
1619
 
          plugin::StorageEngine::dropTable(*session, identifier);
1620
 
        }
 
1551
          table= create_table->table;
 
1552
        pthread_mutex_unlock(&LOCK_open);
1621
1553
      }
1622
1554
      else
1623
1555
      {
1624
 
        if (not (table= session->openTable(create_table, (bool*) 0,
1625
 
                                           DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
1626
 
            not create_info->table_existed)
 
1556
        if (!(table= session->openTable(create_table, (bool*) 0,
 
1557
                                         DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
 
1558
            !create_info->table_existed)
1627
1559
        {
1628
1560
          /*
1629
1561
            This shouldn't happen as creation of temporary table should make
1630
1562
            it preparable for open. But let us do close_temporary_table() here
1631
1563
            just in case.
1632
1564
          */
1633
 
          session->drop_temporary_table(identifier);
 
1565
          session->drop_temporary_table(create_table);
1634
1566
        }
1635
1567
      }
1636
1568
    }
1637
 
    if (not table)                                   // open failed
 
1569
    if (!table)                                   // open failed
1638
1570
      return NULL;
1639
1571
  }
1640
1572
 
1641
1573
  table->reginfo.lock_type=TL_WRITE;
1642
 
  if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
 
1574
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1575
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1643
1576
  {
1644
1577
    if (*lock)
1645
1578
    {
1646
 
      session->unlockTables(*lock);
 
1579
      mysql_unlock_tables(session, *lock);
1647
1580
      *lock= 0;
1648
1581
    }
1649
1582
 
1650
 
    if (not create_info->table_existed)
1651
 
      session->drop_open_table(table, identifier);
 
1583
    if (!create_info->table_existed)
 
1584
      session->drop_open_table(table, create_table->db, create_table->table_name);
1652
1585
    return NULL;
1653
1586
  }
1654
1587
 
1659
1592
int
1660
1593
select_create::prepare(List<Item> &values, Select_Lex_Unit *u)
1661
1594
{
1662
 
  DrizzleLock *extra_lock= NULL;
 
1595
  DRIZZLE_LOCK *extra_lock= NULL;
1663
1596
  /*
1664
 
    For replication, the CREATE-SELECT statement is written
1665
 
    in two pieces: the first transaction messsage contains 
1666
 
    the CREATE TABLE statement as a CreateTableStatement message
1667
 
    necessary to create the table.
1668
 
    
1669
 
    The second transaction message contains all the InsertStatement
1670
 
    and associated InsertRecords that should go into the table.
 
1597
    For row-based replication, the CREATE-SELECT statement is written
 
1598
    in two pieces: the first one contain the CREATE TABLE statement
 
1599
    necessary to create the table and the second part contain the rows
 
1600
    that should go into the table.
 
1601
 
 
1602
    For non-temporary tables, the start of the CREATE-SELECT
 
1603
    implicitly commits the previous transaction, and all events
 
1604
    forming the statement will be stored the transaction cache. At end
 
1605
    of the statement, the entire statement is committed as a
 
1606
    transaction, and all events are written to the binary log.
 
1607
 
 
1608
    On the master, the table is locked for the duration of the
 
1609
    statement, but since the CREATE part is replicated as a simple
 
1610
    statement, there is no way to lock the table for accesses on the
 
1611
    slave.  Hence, we have to hold on to the CREATE part of the
 
1612
    statement until the statement has finished.
1671
1613
   */
1672
1614
 
1673
1615
  unit= u;
1674
1616
 
1675
 
  if (not (table= create_table_from_items(session, create_info, create_table,
1676
 
                                          table_proto,
1677
 
                                          alter_info, &values,
1678
 
                                          is_if_not_exists,
1679
 
                                          &extra_lock, identifier)))
1680
 
  {
 
1617
  /*
 
1618
    Start a statement transaction before the create if we are using
 
1619
    row-based replication for the statement.  If we are creating a
 
1620
    temporary table, we need to start a statement transaction.
 
1621
  */
 
1622
 
 
1623
  if (!(table= create_table_from_items(session, create_info, create_table,
 
1624
                                       table_proto,
 
1625
                                       alter_info, &values,
 
1626
                                       &extra_lock)))
1681
1627
    return(-1);                         // abort() deletes table
1682
 
  }
1683
1628
 
1684
1629
  if (extra_lock)
1685
1630
  {
1686
1631
    assert(m_plock == NULL);
1687
1632
 
1688
 
    if (identifier.isTmp())
 
1633
    if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1689
1634
      m_plock= &m_lock;
1690
1635
    else
1691
1636
      m_plock= &session->extra_lock;
1693
1638
    *m_plock= extra_lock;
1694
1639
  }
1695
1640
 
1696
 
  if (table->getShare()->sizeFields() < values.elements)
 
1641
  if (table->s->fields < values.elements)
1697
1642
  {
1698
1643
    my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
1699
1644
    return(-1);
1700
1645
  }
1701
1646
 
1702
1647
 /* First field to copy */
1703
 
  field= table->getFields() + table->getShare()->sizeFields() - values.elements;
 
1648
  field= table->field+table->s->fields - values.elements;
1704
1649
 
1705
1650
  /* Mark all fields that are given values */
1706
1651
  for (Field **f= field ; *f ; f++)
1707
 
  {
1708
 
    table->setWriteSet((*f)->position());
1709
 
  }
 
1652
    table->setWriteSet((*f)->field_index);
1710
1653
 
1711
1654
  /* Don't set timestamp if used */
1712
1655
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1715
1658
  table->restoreRecordAsDefault();      // Get empty record
1716
1659
  session->cuted_fields=0;
1717
1660
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1718
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
1661
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1719
1662
  if (info.handle_duplicates == DUP_REPLACE)
1720
 
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
 
1663
    table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1721
1664
  if (info.handle_duplicates == DUP_UPDATE)
1722
 
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1723
 
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
 
1665
    table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
 
1666
  table->file->ha_start_bulk_insert((ha_rows) 0);
1724
1667
  session->abort_on_warning= !info.ignore;
1725
1668
  if (check_that_all_fields_are_given_values(session, table, table_list))
1726
1669
    return(1);
1727
1670
  table->mark_columns_needed_for_insert();
1728
 
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
 
1671
  table->file->extra(HA_EXTRA_WRITE_CACHE);
1729
1672
  return(0);
1730
1673
}
1731
1674
 
1732
1675
void select_create::store_values(List<Item> &values)
1733
1676
{
1734
 
  fill_record(session, field, values, true);
 
1677
  fill_record(session, field, values, 1);
1735
1678
}
1736
1679
 
1737
1680
 
1738
1681
void select_create::send_error(uint32_t errcode,const char *err)
1739
1682
{
 
1683
 
 
1684
 
1740
1685
  /*
1741
1686
    This will execute any rollbacks that are necessary before writing
1742
1687
    the transcation cache.
1766
1711
      tables.  This can fail, but we should unlock the table
1767
1712
      nevertheless.
1768
1713
    */
1769
 
    if (!table->getShare()->getType())
 
1714
    if (!table->s->tmp_table)
1770
1715
    {
1771
 
      TransactionServices &transaction_services= TransactionServices::singleton();
1772
 
      transaction_services.autocommitOrRollback(session, 0);
 
1716
      ha_autocommit_or_rollback(session, 0);
1773
1717
      (void) session->endActiveTransaction();
1774
1718
    }
1775
1719
 
1776
 
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1777
 
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
1720
    table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
1721
    table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1778
1722
    if (m_plock)
1779
1723
    {
1780
 
      session->unlockTables(*m_plock);
 
1724
      mysql_unlock_tables(session, *m_plock);
1781
1725
      *m_plock= NULL;
1782
1726
      m_plock= NULL;
1783
1727
    }
1788
1732
 
1789
1733
void select_create::abort()
1790
1734
{
 
1735
 
 
1736
 
1791
1737
  /*
1792
1738
    In select_insert::abort() we roll back the statement, including
1793
1739
    truncating the transaction cache of the binary log. To do this, we
1804
1750
    log state.
1805
1751
  */
1806
1752
  select_insert::abort();
 
1753
  session->transaction.stmt.modified_non_trans_table= false;
 
1754
 
1807
1755
 
1808
1756
  if (m_plock)
1809
1757
  {
1810
 
    session->unlockTables(*m_plock);
 
1758
    mysql_unlock_tables(session, *m_plock);
1811
1759
    *m_plock= NULL;
1812
1760
    m_plock= NULL;
1813
1761
  }
1814
1762
 
1815
1763
  if (table)
1816
1764
  {
1817
 
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1818
 
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1819
 
    if (not create_info->table_existed)
1820
 
      session->drop_open_table(table, identifier);
 
1765
    table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
1766
    table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
1767
    if (!create_info->table_existed)
 
1768
      session->drop_open_table(table, create_table->db, create_table->table_name);
1821
1769
    table= NULL;                                    // Safety
1822
1770
  }
1823
1771
}
1824
1772
 
1825
 
} /* namespace drizzled */
 
1773
 
 
1774
/*****************************************************************************
 
1775
  Instansiate templates
 
1776
*****************************************************************************/
 
1777
 
 
1778
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
1779
template class List_iterator_fast<List_item>;
 
1780
#endif /* HAVE_EXPLICIT_TEMPLATE_INSTANTIATION */