~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Brian Aker
  • Date: 2009-10-16 10:27:33 UTC
  • mfrom: (1183.1.4 merge)
  • Revision ID: brian@gaz-20091016102733-b10po5oup0hjlilh
Merge Engine changes.

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>
25
24
#include <drizzled/probes.h>
26
25
#include <drizzled/sql_base.h>
27
26
#include <drizzled/sql_load.h>
28
 
#include <drizzled/field/epoch.h>
 
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
}
227
208
  end of dispatch_command().
228
209
*/
229
210
 
230
 
bool insert_query(Session *session,TableList *table_list,
 
211
bool mysql_insert(Session *session,TableList *table_list,
231
212
                  List<Item> &fields,
232
213
                  List<List_item> &values_list,
233
214
                  List<Item> &update_fields,
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;
271
252
  values= its++;
272
253
  value_count= values->elements;
273
254
 
274
 
  if (prepare_insert(session, table_list, table, fields, values,
 
255
  if (mysql_prepare_insert(session, table_list, table, fields, values,
275
256
                           update_fields, update_values, duplic, &unused_conds,
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->setAbortOnWarning(false);
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->setAbortOnWarning(false);
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->setAbortOnWarning(false);
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
 
375
 
  session->setAbortOnWarning(not ignore);
 
335
  session->abort_on_warning= !ignore;
376
336
 
377
337
  table->mark_columns_needed_for_insert();
378
338
 
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->setAbortOnWarning(false);
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
  {
494
454
    session->row_count_func= info.copied + info.deleted + info.updated;
495
 
    session->my_ok((ulong) session->rowCount(),
 
455
    session->my_ok((ulong) session->row_count_func,
496
456
                   info.copied + info.deleted + info.touched, id);
497
457
  }
498
458
  else
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
 
    session->my_ok((ulong) session->rowCount(),
 
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->rowCount();
512
 
  session->setAbortOnWarning(false);
513
 
  DRIZZLE_INSERT_DONE(0, session->rowCount());
514
 
 
 
471
  session->abort_on_warning= 0;
 
472
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
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
 
520
487
  Check if table can be updated
521
488
 
522
489
  SYNOPSIS
523
 
     prepare_insert_check_table()
 
490
     mysql_prepare_insert_check_table()
524
491
     session            Thread handle
525
492
     table_list         Table list
526
493
     fields             List of fields to be updated
532
499
     true  ERROR
533
500
*/
534
501
 
535
 
static bool prepare_insert_check_table(Session *session, TableList *table_list,
 
502
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
536
503
                                             List<Item> &,
537
504
                                             bool select_insert)
538
505
{
560
527
  Prepare items in INSERT statement
561
528
 
562
529
  SYNOPSIS
563
 
    prepare_insert()
 
530
    mysql_prepare_insert()
564
531
    session                     Thread handler
565
532
    table_list          Global/local table list
566
533
    table               Table to insert into (can be NULL if table should
587
554
    true  error
588
555
*/
589
556
 
590
 
bool prepare_insert(Session *session, TableList *table_list,
 
557
bool mysql_prepare_insert(Session *session, TableList *table_list,
591
558
                          Table *table, List<Item> &fields, List_item *values,
592
559
                          List<Item> &update_fields, List<Item> &update_values,
593
560
                          enum_duplicates duplic,
610
577
    inserting (for INSERT ... SELECT this is done by changing table_list,
611
578
    because INSERT ... SELECT share Select_Lex it with SELECT.
612
579
  */
613
 
  if (not select_insert)
 
580
  if (!select_insert)
614
581
  {
615
582
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
616
583
         un;
632
599
      return(true);
633
600
  }
634
601
 
635
 
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
 
602
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
636
603
    return(true);
637
604
 
638
605
 
658
625
 
659
626
    if (!res && check_fields)
660
627
    {
661
 
      bool saved_abort_on_warning= session->abortOnWarning();
662
 
 
663
 
      session->setAbortOnWarning(abort_on_warning);
 
628
      bool saved_abort_on_warning= session->abort_on_warning;
 
629
      session->abort_on_warning= abort_on_warning;
664
630
      res= check_that_all_fields_are_given_values(session,
665
631
                                                  table ? table :
666
632
                                                  context->table_list->table,
667
633
                                                  context->table_list);
668
 
      session->setAbortOnWarning(saved_abort_on_warning);
 
634
      session->abort_on_warning= saved_abort_on_warning;
669
635
    }
670
636
 
671
637
    if (!res && duplic == DUP_UPDATE)
676
642
    /* Restore the current context. */
677
643
    ctx_state.restore_state(context, table_list);
678
644
 
679
 
    if (not res)
 
645
    if (!res)
680
646
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
681
647
  }
682
648
 
683
649
  if (res)
684
650
    return(res);
685
651
 
686
 
  if (not table)
 
652
  if (!table)
687
653
    table= table_list->table;
688
654
 
689
 
  if (not select_insert)
 
655
  if (!select_insert)
690
656
  {
691
657
    TableList *duplicate;
692
 
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
 
658
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 1)))
693
659
    {
694
660
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
695
661
 
696
662
      return true;
697
663
    }
698
664
  }
699
 
 
700
665
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
701
666
    table->prepare_for_position();
702
667
 
708
673
 
709
674
static int last_uniq_key(Table *table,uint32_t keynr)
710
675
{
711
 
  while (++keynr < table->getShare()->sizeKeys())
 
676
  while (++keynr < table->s->keys)
712
677
    if (table->key_info[keynr].flags & HA_NOSAME)
713
678
      return 0;
714
679
  return 1;
723
688
     write_record()
724
689
      session   - thread context
725
690
      table - table to which record should be written
726
 
      info  - CopyInfo structure describing handling of duplicates
 
691
      info  - COPY_INFO structure describing handling of duplicates
727
692
              and which is used for counting number of records inserted
728
693
              and deleted.
729
694
 
733
698
    then both on update triggers will work instead. Similarly both on
734
699
    delete triggers will be invoked if we will delete conflicting records.
735
700
 
736
 
    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
737
702
    transactions.
738
703
 
739
704
  RETURN VALUE
742
707
*/
743
708
 
744
709
 
745
 
int write_record(Session *session, Table *table,CopyInfo *info)
 
710
int write_record(Session *session, Table *table,COPY_INFO *info)
746
711
{
747
712
  int error;
748
 
  std::vector<unsigned char> key;
749
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
750
 
  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;
751
716
  uint64_t insert_id_for_cur_row= 0;
752
717
 
753
718
 
757
722
 
758
723
  if (info->handle_duplicates == DUP_REPLACE || info->handle_duplicates == DUP_UPDATE)
759
724
  {
760
 
    while ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
725
    while ((error=table->file->ha_write_row(table->record[0])))
761
726
    {
762
727
      uint32_t key_nr;
763
728
      /*
767
732
        the autogenerated value to avoid session->insert_id_for_cur_row to become
768
733
        0.
769
734
      */
770
 
      if (table->cursor->insert_id_for_cur_row > 0)
771
 
        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;
772
737
      else
773
 
        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;
774
739
      bool is_duplicate_key_error;
775
 
      if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
740
      if (table->file->is_fatal_error(error, HA_CHECK_DUP))
776
741
        goto err;
777
 
      is_duplicate_key_error= table->cursor->is_fatal_error(error, 0);
 
742
      is_duplicate_key_error= table->file->is_fatal_error(error, 0);
778
743
      if (!is_duplicate_key_error)
779
744
      {
780
745
        /*
786
751
          goto gok_or_after_err; /* Ignoring a not fatal error, return 0 */
787
752
        goto err;
788
753
      }
789
 
      if ((int) (key_nr = table->get_dup_key(error)) < 0)
 
754
      if ((int) (key_nr = table->file->get_dup_key(error)) < 0)
790
755
      {
791
756
        error= HA_ERR_FOUND_DUPP_KEY;         /* Database can't find key */
792
757
        goto err;
800
765
      */
801
766
      if (info->handle_duplicates == DUP_REPLACE &&
802
767
          table->next_number_field &&
803
 
          key_nr == table->getShare()->next_number_index &&
 
768
          key_nr == table->s->next_number_index &&
804
769
          (insert_id_for_cur_row > 0))
805
770
        goto err;
806
 
      if (table->cursor->getEngine()->check_flag(HTON_BIT_DUPLICATE_POS))
 
771
      if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
807
772
      {
808
 
        if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
773
        if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
809
774
          goto err;
810
775
      }
811
776
      else
812
777
      {
813
 
        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 */
814
779
        {
815
 
          error=errno;
 
780
          error=my_errno;
816
781
          goto err;
817
782
        }
818
783
 
819
 
        if (not key.size())
 
784
        if (!key)
820
785
        {
821
 
          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
          }
822
791
        }
823
 
        key_copy(&key[0], table->getInsertRecord(), table->key_info+key_nr, 0);
824
 
        if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
825
 
                                                    &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,
826
795
                                                    HA_READ_KEY_EXACT))))
827
796
          goto err;
828
797
      }
833
802
          that matches, is updated. If update causes a conflict again,
834
803
          an error is returned
835
804
        */
836
 
        assert(table->insert_values.size());
 
805
        assert(table->insert_values != NULL);
837
806
        table->storeRecordAsInsert();
838
807
        table->restoreRecord();
839
808
        assert(info->update_fields->elements ==
843
812
                                                 info->ignore))
844
813
          goto before_err;
845
814
 
846
 
        table->cursor->restore_auto_increment(prev_insert_id);
 
815
        table->file->restore_auto_increment(prev_insert_id);
847
816
        if (table->next_number_field)
848
 
          table->cursor->adjust_next_insert_id_after_explicit_value(
 
817
          table->file->adjust_next_insert_id_after_explicit_value(
849
818
            table->next_number_field->val_int());
850
819
        info->touched++;
851
 
 
852
 
        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())
853
823
        {
854
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
855
 
                                                table->getInsertRecord())) &&
 
824
          if ((error=table->file->ha_update_row(table->record[1],
 
825
                                                table->record[0])) &&
856
826
              error != HA_ERR_RECORD_IS_THE_SAME)
857
827
          {
858
828
            if (info->ignore &&
859
 
                !table->cursor->is_fatal_error(error, HA_CHECK_DUP_KEY))
 
829
                !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
860
830
            {
861
831
              goto gok_or_after_err;
862
832
            }
870
840
          /*
871
841
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
872
842
            like a regular UPDATE statement: it should not affect the value of a
873
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
843
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
874
844
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
875
845
            handled separately by Session::arg_of_last_insert_id_function.
876
846
          */
877
 
          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;
878
848
          info->copied++;
879
849
        }
880
850
 
881
851
        if (table->next_number_field)
882
 
          table->cursor->adjust_next_insert_id_after_explicit_value(
 
852
          table->file->adjust_next_insert_id_after_explicit_value(
883
853
            table->next_number_field->val_int());
884
854
        info->touched++;
885
855
 
902
872
          ON UPDATE triggers.
903
873
        */
904
874
        if (last_uniq_key(table,key_nr) &&
905
 
            !table->cursor->referenced_by_foreign_key() &&
 
875
            !table->file->referenced_by_foreign_key() &&
906
876
            (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
907
877
             table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
908
878
        {
909
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
910
 
                                                table->getInsertRecord())) &&
 
879
          if ((error=table->file->ha_update_row(table->record[1],
 
880
                                                table->record[0])) &&
911
881
              error != HA_ERR_RECORD_IS_THE_SAME)
912
882
            goto err;
913
883
          if (error != HA_ERR_RECORD_IS_THE_SAME)
914
884
            info->deleted++;
915
885
          else
916
886
            error= 0;
917
 
          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);
918
888
          /*
919
889
            Since we pretend that we have done insert we should call
920
890
            its after triggers.
923
893
        }
924
894
        else
925
895
        {
926
 
          if ((error=table->cursor->deleteRecord(table->getUpdateRecord())))
 
896
          if ((error=table->file->ha_delete_row(table->record[1])))
927
897
            goto err;
928
898
          info->deleted++;
929
 
          if (!table->cursor->has_transactions())
930
 
            session->transaction.stmt.markModifiedNonTransData();
 
899
          if (!table->file->has_transactions())
 
900
            session->transaction.stmt.modified_non_trans_table= true;
931
901
          /* Let us attempt do write_row() once more */
932
902
        }
933
903
      }
934
904
    }
935
 
    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);
936
906
    /*
937
907
      Restore column maps if they where replaced during an duplicate key
938
908
      problem.
939
909
    */
940
910
    if (table->read_set != save_read_set ||
941
911
        table->write_set != save_write_set)
942
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
912
      table->column_bitmaps_set(save_read_set, save_write_set);
943
913
  }
944
 
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
914
  else if ((error=table->file->ha_write_row(table->record[0])))
945
915
  {
946
916
    if (!info->ignore ||
947
 
        table->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
917
        table->file->is_fatal_error(error, HA_CHECK_DUP))
948
918
      goto err;
949
 
    table->cursor->restore_auto_increment(prev_insert_id);
 
919
    table->file->restore_auto_increment(prev_insert_id);
950
920
    goto gok_or_after_err;
951
921
  }
952
922
 
953
923
after_n_copied_inc:
954
924
  info->copied++;
955
 
  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);
956
926
 
957
927
gok_or_after_err:
958
 
  if (!table->cursor->has_transactions())
959
 
    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;
960
932
  return(0);
961
933
 
962
934
err:
964
936
  /* current_select is NULL if this is a delayed insert */
965
937
  if (session->lex->current_select)
966
938
    session->lex->current_select->no_error= 0;        // Give error
967
 
  table->print_error(error,MYF(0));
 
939
  table->file->print_error(error,MYF(0));
968
940
 
969
941
before_err:
970
 
  table->cursor->restore_auto_increment(prev_insert_id);
971
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
972
 
  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);
973
947
}
974
948
 
975
949
 
982
956
{
983
957
  int err= 0;
984
958
 
985
 
  for (Field **field=entry->getFields() ; *field ; field++)
 
959
  for (Field **field=entry->field ; *field ; field++)
986
960
  {
987
961
    if (((*field)->isWriteSet()) == false)
988
962
    {
1016
990
      }
1017
991
    }
1018
992
  }
1019
 
  return session->abortOnWarning() ? err : 0;
 
993
  return session->abort_on_warning ? err : 0;
1020
994
}
1021
995
 
1022
996
/***************************************************************************
1028
1002
  make insert specific preparation and checks after opening tables
1029
1003
 
1030
1004
  SYNOPSIS
1031
 
    insert_select_prepare()
 
1005
    mysql_insert_select_prepare()
1032
1006
    session         thread handler
1033
1007
 
1034
1008
  RETURN
1036
1010
    true  Error
1037
1011
*/
1038
1012
 
1039
 
bool insert_select_prepare(Session *session)
 
1013
bool mysql_insert_select_prepare(Session *session)
1040
1014
{
1041
1015
  LEX *lex= session->lex;
1042
1016
  Select_Lex *select_lex= &lex->select_lex;
1046
1020
    clause if table is VIEW
1047
1021
  */
1048
1022
 
1049
 
  if (prepare_insert(session, lex->query_tables,
 
1023
  if (mysql_prepare_insert(session, lex->query_tables,
1050
1024
                           lex->query_tables->table, lex->field_list, 0,
1051
1025
                           lex->update_list, lex->value_list,
1052
1026
                           lex->duplicates,
1070
1044
                             List<Item> *update_fields,
1071
1045
                             List<Item> *update_values,
1072
1046
                             enum_duplicates duplic,
1073
 
                             bool ignore_check_option_errors) :
1074
 
  table_list(table_list_par), table(table_par), fields(fields_par),
1075
 
  autoinc_value_of_last_inserted_row(0),
1076
 
  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)
1077
1051
{
 
1052
  memset(&info, 0, sizeof(info));
1078
1053
  info.handle_duplicates= duplic;
1079
1054
  info.ignore= ignore_check_option_errors;
1080
1055
  info.update_fields= update_fields;
1105
1080
 
1106
1081
  if (!res && fields->elements)
1107
1082
  {
1108
 
    bool saved_abort_on_warning= session->abortOnWarning();
1109
 
    session->setAbortOnWarning(not info.ignore);
 
1083
    bool saved_abort_on_warning= session->abort_on_warning;
 
1084
    session->abort_on_warning= !info.ignore;
1110
1085
    res= check_that_all_fields_are_given_values(session, table_list->table,
1111
1086
                                                table_list);
1112
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1087
    session->abort_on_warning= saved_abort_on_warning;
1113
1088
  }
1114
1089
 
1115
1090
  if (info.handle_duplicates == DUP_UPDATE && !res)
1179
1154
    Is table which we are changing used somewhere in other parts of
1180
1155
    query
1181
1156
  */
1182
 
  if (unique_table(table_list, table_list->next_global))
 
1157
  if (unique_table(session, table_list, table_list->next_global, 0))
1183
1158
  {
1184
1159
    /* Using same table for INSERT and SELECT */
1185
1160
    lex->current_select->options|= OPTION_BUFFER_RESULT;
1196
1171
      We won't start bulk inserts at all if this statement uses functions or
1197
1172
      should invoke triggers since they may access to the same table too.
1198
1173
    */
1199
 
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
 
1174
    table->file->ha_start_bulk_insert((ha_rows) 0);
1200
1175
  }
1201
1176
  table->restoreRecordAsDefault();              // Get empty record
1202
1177
  table->next_number_field=table->found_next_number_field;
1203
1178
 
1204
1179
  session->cuted_fields=0;
1205
 
 
1206
1180
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1207
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1208
 
 
 
1181
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1209
1182
  if (info.handle_duplicates == DUP_REPLACE)
1210
 
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1211
 
 
 
1183
    table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1212
1184
  if (info.handle_duplicates == DUP_UPDATE)
1213
 
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1214
 
 
1215
 
  session->setAbortOnWarning(not info.ignore);
 
1185
    table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
 
1186
  session->abort_on_warning= !info.ignore;
1216
1187
  table->mark_columns_needed_for_insert();
1217
1188
 
1218
1189
 
1240
1211
{
1241
1212
 
1242
1213
  if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1243
 
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
 
1214
    table->file->ha_start_bulk_insert((ha_rows) 0);
1244
1215
  return(0);
1245
1216
}
1246
1217
 
1258
1229
  {
1259
1230
    table->next_number_field=0;
1260
1231
    table->auto_increment_field_not_null= false;
1261
 
    table->cursor->ha_reset();
 
1232
    table->file->ha_reset();
1262
1233
  }
1263
1234
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1264
 
  session->setAbortOnWarning(false);
 
1235
  session->abort_on_warning= 0;
1265
1236
  return;
1266
1237
}
1267
1238
 
1274
1245
  if (unit->offset_limit_cnt)
1275
1246
  {                                             // using limit offset,count
1276
1247
    unit->offset_limit_cnt--;
1277
 
    return false;
 
1248
    return(0);
1278
1249
  }
1279
1250
 
1280
1251
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1281
1252
  store_values(values);
1282
1253
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1283
1254
  if (session->is_error())
1284
 
    return true;
 
1255
    return(1);
1285
1256
 
1286
1257
  // Release latches in case bulk insert takes a long time
1287
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1258
  plugin::StorageEngine::releaseTemporaryLatches(session);
1288
1259
 
1289
1260
  error= write_record(session, table, &info);
1290
 
  table->auto_increment_field_not_null= false;
1291
1261
 
1292
1262
  if (!error)
1293
1263
  {
1326
1296
void select_insert::store_values(List<Item> &values)
1327
1297
{
1328
1298
  if (fields->elements)
1329
 
    fill_record(session, *fields, values, true);
 
1299
    fill_record(session, *fields, values, 1);
1330
1300
  else
1331
 
    fill_record(session, table->getFields(), values, true);
 
1301
    fill_record(session, table->field, values, 1);
1332
1302
}
1333
1303
 
1334
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1304
void select_insert::send_error(uint32_t errcode,const char *err)
1335
1305
{
 
1306
 
 
1307
 
1336
1308
  my_message(errcode, err, MYF(0));
 
1309
 
 
1310
  return;
1337
1311
}
1338
1312
 
1339
1313
 
1340
1314
bool select_insert::send_eof()
1341
1315
{
1342
1316
  int error;
1343
 
  bool const trans_table= table->cursor->has_transactions();
 
1317
  bool const trans_table= table->file->has_transactions();
1344
1318
  uint64_t id;
1345
1319
  bool changed;
1346
1320
 
1347
 
  error= table->cursor->ha_end_bulk_insert();
1348
 
  table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1349
 
  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);
1350
1324
 
1351
1325
  if ((changed= (info.copied || info.deleted || info.updated)))
1352
1326
  {
1353
1327
    /*
1354
1328
      We must invalidate the table in the query cache before binlog writing
1355
 
      and autocommitOrRollback.
 
1329
      and ha_autocommit_or_rollback.
1356
1330
    */
1357
 
    if (session->transaction.stmt.hasModifiedNonTransData())
1358
 
      session->transaction.all.markModifiedNonTransData();
 
1331
    if (session->transaction.stmt.modified_non_trans_table)
 
1332
      session->transaction.all.modified_non_trans_table= true;
1359
1333
  }
1360
1334
  assert(trans_table || !changed ||
1361
 
              session->transaction.stmt.hasModifiedNonTransData());
 
1335
              session->transaction.stmt.modified_non_trans_table);
1362
1336
 
1363
 
  table->cursor->ha_release_auto_increment();
 
1337
  table->file->ha_release_auto_increment();
1364
1338
 
1365
1339
  if (error)
1366
1340
  {
1367
 
    table->print_error(error,MYF(0));
 
1341
    table->file->print_error(error,MYF(0));
1368
1342
    DRIZZLE_INSERT_SELECT_DONE(error, 0);
1369
1343
    return 1;
1370
1344
  }
1371
1345
  char buff[160];
1372
1346
  if (info.ignore)
1373
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1347
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1374
1348
            (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
1375
1349
  else
1376
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1350
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1377
1351
            (ulong) (info.deleted+info.updated), (ulong) session->cuted_fields);
1378
1352
  session->row_count_func= info.copied + info.deleted + info.updated;
1379
1353
 
1382
1356
    (session->arg_of_last_insert_id_function ?
1383
1357
     session->first_successful_insert_id_in_prev_stmt :
1384
1358
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1385
 
  session->my_ok((ulong) session->rowCount(),
 
1359
  session->my_ok((ulong) session->row_count_func,
1386
1360
                 info.copied + info.deleted + info.touched, id, buff);
1387
 
  session->status_var.inserted_row_count+= session->rowCount(); 
1388
 
  DRIZZLE_INSERT_SELECT_DONE(0, session->rowCount());
 
1361
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1389
1362
  return 0;
1390
1363
}
1391
1364
 
1402
1375
  {
1403
1376
    bool changed, transactional_table;
1404
1377
 
1405
 
    table->cursor->ha_end_bulk_insert();
 
1378
    table->file->ha_end_bulk_insert();
1406
1379
 
1407
1380
    /*
1408
1381
      If at least one row has been inserted/modified and will stay in
1419
1392
      zero, so no check for that is made.
1420
1393
    */
1421
1394
    changed= (info.copied || info.deleted || info.updated);
1422
 
    transactional_table= table->cursor->has_transactions();
 
1395
    transactional_table= table->file->has_transactions();
1423
1396
    assert(transactional_table || !changed ||
1424
 
                session->transaction.stmt.hasModifiedNonTransData());
1425
 
    table->cursor->ha_release_auto_increment();
 
1397
                session->transaction.stmt.modified_non_trans_table);
 
1398
    table->file->ha_release_auto_increment();
1426
1399
  }
1427
1400
 
1428
1401
  if (DRIZZLE_INSERT_SELECT_DONE_ENABLED())
1454
1427
      items        in     List of items which should be used to produce rest
1455
1428
                          of fields for the table (corresponding fields will
1456
1429
                          be added to the end of alter_info->create_list)
1457
 
      lock         out    Pointer to the DrizzleLock object for table created
 
1430
      lock         out    Pointer to the DRIZZLE_LOCK object for table created
1458
1431
                          (or open temporary table) will be returned in this
1459
1432
                          parameter. Since this table is not included in
1460
1433
                          Session::lock caller is responsible for explicitly
1482
1455
 
1483
1456
static Table *create_table_from_items(Session *session, HA_CREATE_INFO *create_info,
1484
1457
                                      TableList *create_table,
1485
 
                                      message::Table &table_proto,
 
1458
                                      message::Table *table_proto,
1486
1459
                                      AlterInfo *alter_info,
1487
1460
                                      List<Item> *items,
1488
 
                                      bool is_if_not_exists,
1489
 
                                      DrizzleLock **lock,
1490
 
                                      identifier::Table::const_reference identifier)
 
1461
                                      DRIZZLE_LOCK **lock)
1491
1462
{
1492
 
  TableShare share(message::Table::INTERNAL);
 
1463
  Table tmp_table;              // Used during 'CreateField()'
 
1464
  TableShare share;
 
1465
  Table *table= 0;
1493
1466
  uint32_t select_field_count= items->elements;
1494
1467
  /* Add selected items to field list */
1495
1468
  List_iterator_fast<Item> it(*items);
1496
1469
  Item *item;
1497
1470
  Field *tmp_field;
 
1471
  bool not_used;
1498
1472
 
1499
 
  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)
1500
1475
  {
1501
1476
    /* Table already exists and was open at openTablesLock() stage. */
1502
 
    if (is_if_not_exists)
 
1477
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1503
1478
    {
1504
1479
      create_info->table_existed= 1;            // Mark that table existed
1505
1480
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1506
1481
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1507
 
                          create_table->getTableName());
 
1482
                          create_table->table_name);
1508
1483
      return create_table->table;
1509
1484
    }
1510
1485
 
1511
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1486
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1512
1487
    return NULL;
1513
1488
  }
1514
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++))
1515
1503
  {
1516
 
    table::Shell tmp_table(share);              // Used during 'CreateField()'
1517
 
 
1518
 
    if (not table_proto.engine().name().compare("MyISAM"))
1519
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1520
 
    else if (not table_proto.engine().name().compare("MEMORY"))
1521
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1522
 
 
1523
 
    tmp_table.in_use= session;
1524
 
 
1525
 
    while ((item=it++))
1526
 
    {
1527
 
      CreateField *cr_field;
1528
 
      Field *field, *def_field;
1529
 
      if (item->type() == Item::FUNC_ITEM)
1530
 
      {
1531
 
        if (item->result_type() != STRING_RESULT)
1532
 
        {
1533
 
          field= item->tmp_table_field(&tmp_table);
1534
 
        }
1535
 
        else
1536
 
        {
1537
 
          field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1538
 
        }
1539
 
      }
 
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);
1540
1509
      else
1541
 
      {
1542
 
        field= create_tmp_field(session, &tmp_table, item, item->type(),
1543
 
                                (Item ***) 0, &tmp_field, &def_field, false,
1544
 
                                false, false, 0);
1545
 
      }
1546
 
 
1547
 
      if (!field ||
1548
 
          !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1549
 
                                            ((Item_field *)item)->field :
1550
 
                                            (Field*) 0))))
1551
 
      {
1552
 
        return NULL;
1553
 
      }
1554
 
 
1555
 
      if (item->maybe_null)
1556
 
      {
1557
 
        cr_field->flags &= ~NOT_NULL_FLAG;
1558
 
      }
1559
 
 
1560
 
      alter_info->create_list.push_back(cr_field);
1561
 
    }
 
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);
1562
1523
  }
1563
1524
 
1564
1525
  /*
1568
1529
    creating base table on which name we have exclusive lock. So code below
1569
1530
    should not cause deadlocks or races.
1570
1531
  */
1571
 
  Table *table= 0;
1572
1532
  {
1573
 
    if (not create_table_no_lock(session,
1574
 
                                 identifier,
1575
 
                                 create_info,
1576
 
                                 table_proto,
1577
 
                                 alter_info,
1578
 
                                 false,
1579
 
                                 select_field_count,
1580
 
                                 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))
1581
1539
    {
1582
 
      if (create_info->table_existed && not identifier.isTmp())
 
1540
      if (create_info->table_existed &&
 
1541
          !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1583
1542
      {
1584
1543
        /*
1585
1544
          This means that someone created table underneath server
1586
1545
          or it was created via different mysqld front-end to the
1587
1546
          cluster. We don't have much options but throw an error.
1588
1547
        */
1589
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1548
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1590
1549
        return NULL;
1591
1550
      }
1592
1551
 
1593
 
      if (not identifier.isTmp())
 
1552
      if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1594
1553
      {
1595
 
        /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1596
 
        boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1597
 
 
1598
 
        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))
1599
1556
        {
1600
 
          table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1601
 
 
1602
 
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1603
 
          {
1604
 
            (void)plugin::StorageEngine::dropTable(*session, identifier);
1605
 
          }
1606
 
          else
1607
 
          {
1608
 
            table= create_table->table;
1609
 
          }
 
1557
          quick_rm_table(create_info->db_type, create_table->db,
 
1558
                         create_table->table_name, false);
1610
1559
        }
1611
1560
        else
1612
 
        {
1613
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
1614
 
        }
 
1561
          table= create_table->table;
 
1562
        pthread_mutex_unlock(&LOCK_open);
1615
1563
      }
1616
1564
      else
1617
1565
      {
1618
 
        if (not (table= session->openTable(create_table, (bool*) 0,
1619
 
                                           DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
1620
 
            not create_info->table_existed)
 
1566
        if (!(table= session->openTable(create_table, (bool*) 0,
 
1567
                                         DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
 
1568
            !create_info->table_existed)
1621
1569
        {
1622
1570
          /*
1623
1571
            This shouldn't happen as creation of temporary table should make
1624
1572
            it preparable for open. But let us do close_temporary_table() here
1625
1573
            just in case.
1626
1574
          */
1627
 
          session->drop_temporary_table(identifier);
 
1575
          session->drop_temporary_table(create_table);
1628
1576
        }
1629
1577
      }
1630
1578
    }
1631
 
    if (not table)                                   // open failed
 
1579
    if (!table)                                   // open failed
1632
1580
      return NULL;
1633
1581
  }
1634
1582
 
1635
1583
  table->reginfo.lock_type=TL_WRITE;
1636
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1584
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1585
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1637
1586
  {
1638
1587
    if (*lock)
1639
1588
    {
1640
 
      session->unlockTables(*lock);
 
1589
      mysql_unlock_tables(session, *lock);
1641
1590
      *lock= 0;
1642
1591
    }
1643
1592
 
1644
 
    if (not create_info->table_existed)
1645
 
      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);
1646
1595
    return NULL;
1647
1596
  }
1648
1597
 
1653
1602
int
1654
1603
select_create::prepare(List<Item> &values, Select_Lex_Unit *u)
1655
1604
{
1656
 
  DrizzleLock *extra_lock= NULL;
 
1605
  DRIZZLE_LOCK *extra_lock= NULL;
1657
1606
  /*
1658
 
    For replication, the CREATE-SELECT statement is written
1659
 
    in two pieces: the first transaction messsage contains 
1660
 
    the CREATE TABLE statement as a CreateTableStatement message
1661
 
    necessary to create the table.
1662
 
    
1663
 
    The second transaction message contains all the InsertStatement
1664
 
    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.
1665
1623
   */
1666
1624
 
1667
1625
  unit= u;
1668
1626
 
1669
 
  if (not (table= create_table_from_items(session, create_info, create_table,
1670
 
                                          table_proto,
1671
 
                                          alter_info, &values,
1672
 
                                          is_if_not_exists,
1673
 
                                          &extra_lock, identifier)))
1674
 
  {
 
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)))
1675
1637
    return(-1);                         // abort() deletes table
1676
 
  }
1677
1638
 
1678
1639
  if (extra_lock)
1679
1640
  {
1680
1641
    assert(m_plock == NULL);
1681
1642
 
1682
 
    if (identifier.isTmp())
 
1643
    if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1683
1644
      m_plock= &m_lock;
1684
1645
    else
1685
1646
      m_plock= &session->extra_lock;
1687
1648
    *m_plock= extra_lock;
1688
1649
  }
1689
1650
 
1690
 
  if (table->getShare()->sizeFields() < values.elements)
 
1651
  if (table->s->fields < values.elements)
1691
1652
  {
1692
1653
    my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
1693
1654
    return(-1);
1694
1655
  }
1695
1656
 
1696
1657
 /* First field to copy */
1697
 
  field= table->getFields() + table->getShare()->sizeFields() - values.elements;
 
1658
  field= table->field+table->s->fields - values.elements;
1698
1659
 
1699
1660
  /* Mark all fields that are given values */
1700
1661
  for (Field **f= field ; *f ; f++)
1701
 
  {
1702
 
    table->setWriteSet((*f)->position());
1703
 
  }
 
1662
    table->setWriteSet((*f)->field_index);
1704
1663
 
1705
1664
  /* Don't set timestamp if used */
1706
1665
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1709
1668
  table->restoreRecordAsDefault();      // Get empty record
1710
1669
  session->cuted_fields=0;
1711
1670
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1712
 
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1713
 
 
 
1671
    table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1714
1672
  if (info.handle_duplicates == DUP_REPLACE)
1715
 
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1716
 
 
 
1673
    table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1717
1674
  if (info.handle_duplicates == DUP_UPDATE)
1718
 
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1719
 
 
1720
 
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1721
 
  session->setAbortOnWarning(not info.ignore);
 
1675
    table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
 
1676
  table->file->ha_start_bulk_insert((ha_rows) 0);
 
1677
  session->abort_on_warning= !info.ignore;
1722
1678
  if (check_that_all_fields_are_given_values(session, table, table_list))
1723
1679
    return(1);
1724
 
 
1725
1680
  table->mark_columns_needed_for_insert();
1726
 
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
 
1681
  table->file->extra(HA_EXTRA_WRITE_CACHE);
1727
1682
  return(0);
1728
1683
}
1729
1684
 
1730
1685
void select_create::store_values(List<Item> &values)
1731
1686
{
1732
 
  fill_record(session, field, values, true);
 
1687
  fill_record(session, field, values, 1);
1733
1688
}
1734
1689
 
1735
1690
 
1736
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1691
void select_create::send_error(uint32_t errcode,const char *err)
1737
1692
{
 
1693
 
 
1694
 
1738
1695
  /*
1739
1696
    This will execute any rollbacks that are necessary before writing
1740
1697
    the transcation cache.
1747
1704
 
1748
1705
  */
1749
1706
  select_insert::send_error(errcode, err);
 
1707
 
 
1708
  return;
1750
1709
}
1751
1710
 
1752
1711
 
1762
1721
      tables.  This can fail, but we should unlock the table
1763
1722
      nevertheless.
1764
1723
    */
1765
 
    if (!table->getShare()->getType())
 
1724
    if (!table->s->tmp_table)
1766
1725
    {
1767
 
      TransactionServices &transaction_services= TransactionServices::singleton();
1768
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1726
      ha_autocommit_or_rollback(session, 0);
1769
1727
      (void) session->endActiveTransaction();
1770
1728
    }
1771
1729
 
1772
 
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1773
 
    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);
1774
1732
    if (m_plock)
1775
1733
    {
1776
 
      session->unlockTables(*m_plock);
 
1734
      mysql_unlock_tables(session, *m_plock);
1777
1735
      *m_plock= NULL;
1778
1736
      m_plock= NULL;
1779
1737
    }
1784
1742
 
1785
1743
void select_create::abort()
1786
1744
{
 
1745
 
 
1746
 
1787
1747
  /*
1788
1748
    In select_insert::abort() we roll back the statement, including
1789
1749
    truncating the transaction cache of the binary log. To do this, we
1800
1760
    log state.
1801
1761
  */
1802
1762
  select_insert::abort();
 
1763
  session->transaction.stmt.modified_non_trans_table= false;
 
1764
 
1803
1765
 
1804
1766
  if (m_plock)
1805
1767
  {
1806
 
    session->unlockTables(*m_plock);
 
1768
    mysql_unlock_tables(session, *m_plock);
1807
1769
    *m_plock= NULL;
1808
1770
    m_plock= NULL;
1809
1771
  }
1810
1772
 
1811
1773
  if (table)
1812
1774
  {
1813
 
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1814
 
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1815
 
    if (not create_info->table_existed)
1816
 
      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);
1817
1779
    table= NULL;                                    // Safety
1818
1780
  }
1819
1781
}
1820
1782
 
1821
 
} /* 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 */