~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Patrick Galbraith
  • Date: 2009-10-08 22:42:05 UTC
  • mto: (1166.5.3 memcached_functions)
  • mto: This revision was merged to the branch mainline in revision 1189.
  • Revision ID: patg@patrick-galbraiths-macbook-pro.local-20091008224205-gq1pehjsivvx0qo9
Starting over with a fresh tree, moved in memcached functions.

Memcached Functions for Drizzle. 

All tests pass.

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