~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

Merge Stewart.

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
19
#include "config.h"
20
 
#include <cstdio>
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
29
#include "drizzled/sql_table.h"
31
30
#include "drizzled/pthread_globals.h"
32
31
#include "drizzled/transaction_services.h"
33
32
#include "drizzled/plugin/transactional_storage_engine.h"
34
33
 
35
 
#include "drizzled/table/shell.h"
36
 
 
37
34
namespace drizzled
38
35
{
39
36
 
70
67
 
71
68
  if (fields.elements == 0 && values.elements != 0)
72
69
  {
73
 
    if (values.elements != table->getShare()->sizeFields())
 
70
    if (values.elements != table->s->fields)
74
71
    {
75
72
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
76
73
      return -1;
123
120
    if (table->timestamp_field) // Don't automaticly set timestamp if used
124
121
    {
125
122
      if (table->timestamp_field->isWriteSet())
126
 
      {
127
123
        clear_timestamp_auto_bits(table->timestamp_field_type,
128
124
                                  TIMESTAMP_AUTO_SET_ON_INSERT);
129
 
      }
130
125
      else
131
126
      {
132
 
        table->setWriteSet(table->timestamp_field->position());
 
127
        table->setWriteSet(table->timestamp_field->field_index);
133
128
      }
134
129
    }
135
130
  }
170
165
      Unmark the timestamp field so that we can check if this is modified
171
166
      by update_fields
172
167
    */
173
 
    timestamp_mark= table->write_set->test(table->timestamp_field->position());
174
 
    table->write_set->reset(table->timestamp_field->position());
 
168
    timestamp_mark= table->write_set->testAndClear(table->timestamp_field->field_index);
175
169
  }
176
170
 
177
171
  /* Check the fields we are going to modify */
182
176
  {
183
177
    /* Don't set timestamp column if this is modified. */
184
178
    if (table->timestamp_field->isWriteSet())
185
 
    {
186
179
      clear_timestamp_auto_bits(table->timestamp_field_type,
187
180
                                TIMESTAMP_AUTO_SET_ON_UPDATE);
188
 
    }
189
 
 
190
181
    if (timestamp_mark)
191
 
    {
192
 
      table->setWriteSet(table->timestamp_field->position());
193
 
    }
 
182
      table->setWriteSet(table->timestamp_field->field_index);
194
183
  }
195
184
  return 0;
196
185
}
227
216
  end of dispatch_command().
228
217
*/
229
218
 
230
 
bool insert_query(Session *session,TableList *table_list,
 
219
bool mysql_insert(Session *session,TableList *table_list,
231
220
                  List<Item> &fields,
232
221
                  List<List_item> &values_list,
233
222
                  List<Item> &update_fields,
241
230
  uint32_t value_count;
242
231
  ulong counter = 1;
243
232
  uint64_t id;
244
 
  CopyInfo info;
 
233
  COPY_INFO info;
245
234
  Table *table= 0;
246
235
  List_iterator_fast<List_item> its(values_list);
247
236
  List_item *values;
271
260
  values= its++;
272
261
  value_count= values->elements;
273
262
 
274
 
  if (prepare_insert(session, table_list, table, fields, values,
 
263
  if (mysql_prepare_insert(session, table_list, table, fields, values,
275
264
                           update_fields, update_values, duplic, &unused_conds,
276
265
                           false,
277
266
                           (fields.elements || !value_count ||
278
267
                            (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
 
  }
 
268
    goto abort;
288
269
 
289
270
  /* mysql_prepare_insert set table_list->table if it was not set */
290
271
  table= table_list->table;
315
296
    if (values->elements != value_count)
316
297
    {
317
298
      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;
 
299
      goto abort;
327
300
    }
328
301
    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
 
    }
 
302
      goto abort;
338
303
  }
339
304
  its.rewind ();
340
305
 
344
309
  /*
345
310
    Fill in the given fields and dump it to the table cursor
346
311
  */
 
312
  memset(&info, 0, sizeof(info));
347
313
  info.ignore= ignore;
348
314
  info.handle_duplicates=duplic;
349
315
  info.update_fields= &update_fields;
354
320
    For single line insert, generate an error if try to set a NOT NULL field
355
321
    to NULL.
356
322
  */
357
 
  session->count_cuted_fields= ignore ? CHECK_FIELD_WARN : CHECK_FIELD_ERROR_FOR_NULL;
358
 
 
 
323
  session->count_cuted_fields= ((values_list.elements == 1 &&
 
324
                                 !ignore) ?
 
325
                                CHECK_FIELD_ERROR_FOR_NULL :
 
326
                                CHECK_FIELD_WARN);
359
327
  session->cuted_fields = 0L;
360
328
  table->next_number_field=table->found_next_number_field;
361
329
 
372
340
  }
373
341
 
374
342
 
375
 
  session->setAbortOnWarning(not ignore);
 
343
  session->abort_on_warning= !ignore;
376
344
 
377
345
  table->mark_columns_needed_for_insert();
378
346
 
401
369
    {
402
370
      table->restoreRecordAsDefault();  // Get empty record
403
371
 
404
 
      if (fill_record(session, table->getFields(), *values))
 
372
      if (fill_record(session, table->field, *values))
405
373
      {
406
374
        if (values_list.elements != 1 && ! session->is_error())
407
375
        {
478
446
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
479
447
 
480
448
  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
 
 
 
449
    goto abort;
491
450
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
492
451
                                    !session->cuted_fields))
493
452
  {
494
453
    session->row_count_func= info.copied + info.deleted + info.updated;
495
 
    session->my_ok((ulong) session->rowCount(),
 
454
    session->my_ok((ulong) session->row_count_func,
496
455
                   info.copied + info.deleted + info.touched, id);
497
456
  }
498
457
  else
499
458
  {
500
459
    char buff[160];
501
460
    if (ignore)
502
 
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
461
      sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
503
462
              (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
504
463
    else
505
 
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
464
      sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
506
465
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
507
466
    session->row_count_func= info.copied + info.deleted + info.updated;
508
 
    session->my_ok((ulong) session->rowCount(),
 
467
    session->my_ok((ulong) session->row_count_func,
509
468
                   info.copied + info.deleted + info.touched, id, buff);
510
469
  }
511
 
  session->status_var.inserted_row_count+= session->rowCount();
512
 
  session->setAbortOnWarning(false);
513
 
  DRIZZLE_INSERT_DONE(0, session->rowCount());
514
 
 
 
470
  session->abort_on_warning= 0;
 
471
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
515
472
  return false;
 
473
 
 
474
abort:
 
475
  if (table != NULL)
 
476
    table->cursor->ha_release_auto_increment();
 
477
  if (!joins_freed)
 
478
    free_underlaid_joins(session, &session->lex->select_lex);
 
479
  session->abort_on_warning= 0;
 
480
  DRIZZLE_INSERT_DONE(1, 0);
 
481
  return true;
516
482
}
517
483
 
518
484
 
520
486
  Check if table can be updated
521
487
 
522
488
  SYNOPSIS
523
 
     prepare_insert_check_table()
 
489
     mysql_prepare_insert_check_table()
524
490
     session            Thread handle
525
491
     table_list         Table list
526
492
     fields             List of fields to be updated
532
498
     true  ERROR
533
499
*/
534
500
 
535
 
static bool prepare_insert_check_table(Session *session, TableList *table_list,
 
501
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
536
502
                                             List<Item> &,
537
503
                                             bool select_insert)
538
504
{
560
526
  Prepare items in INSERT statement
561
527
 
562
528
  SYNOPSIS
563
 
    prepare_insert()
 
529
    mysql_prepare_insert()
564
530
    session                     Thread handler
565
531
    table_list          Global/local table list
566
532
    table               Table to insert into (can be NULL if table should
587
553
    true  error
588
554
*/
589
555
 
590
 
bool prepare_insert(Session *session, TableList *table_list,
 
556
bool mysql_prepare_insert(Session *session, TableList *table_list,
591
557
                          Table *table, List<Item> &fields, List_item *values,
592
558
                          List<Item> &update_fields, List<Item> &update_values,
593
559
                          enum_duplicates duplic,
610
576
    inserting (for INSERT ... SELECT this is done by changing table_list,
611
577
    because INSERT ... SELECT share Select_Lex it with SELECT.
612
578
  */
613
 
  if (not select_insert)
 
579
  if (!select_insert)
614
580
  {
615
581
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
616
582
         un;
632
598
      return(true);
633
599
  }
634
600
 
635
 
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
 
601
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
636
602
    return(true);
637
603
 
638
604
 
658
624
 
659
625
    if (!res && check_fields)
660
626
    {
661
 
      bool saved_abort_on_warning= session->abortOnWarning();
662
 
 
663
 
      session->setAbortOnWarning(abort_on_warning);
 
627
      bool saved_abort_on_warning= session->abort_on_warning;
 
628
      session->abort_on_warning= abort_on_warning;
664
629
      res= check_that_all_fields_are_given_values(session,
665
630
                                                  table ? table :
666
631
                                                  context->table_list->table,
667
632
                                                  context->table_list);
668
 
      session->setAbortOnWarning(saved_abort_on_warning);
 
633
      session->abort_on_warning= saved_abort_on_warning;
669
634
    }
670
635
 
671
636
    if (!res && duplic == DUP_UPDATE)
676
641
    /* Restore the current context. */
677
642
    ctx_state.restore_state(context, table_list);
678
643
 
679
 
    if (not res)
 
644
    if (!res)
680
645
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
681
646
  }
682
647
 
683
648
  if (res)
684
649
    return(res);
685
650
 
686
 
  if (not table)
 
651
  if (!table)
687
652
    table= table_list->table;
688
653
 
689
 
  if (not select_insert)
 
654
  if (!select_insert)
690
655
  {
691
656
    TableList *duplicate;
692
657
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
696
661
      return true;
697
662
    }
698
663
  }
699
 
 
700
664
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
701
665
    table->prepare_for_position();
702
666
 
708
672
 
709
673
static int last_uniq_key(Table *table,uint32_t keynr)
710
674
{
711
 
  while (++keynr < table->getShare()->sizeKeys())
 
675
  while (++keynr < table->s->keys)
712
676
    if (table->key_info[keynr].flags & HA_NOSAME)
713
677
      return 0;
714
678
  return 1;
723
687
     write_record()
724
688
      session   - thread context
725
689
      table - table to which record should be written
726
 
      info  - CopyInfo structure describing handling of duplicates
 
690
      info  - COPY_INFO structure describing handling of duplicates
727
691
              and which is used for counting number of records inserted
728
692
              and deleted.
729
693
 
742
706
*/
743
707
 
744
708
 
745
 
int write_record(Session *session, Table *table,CopyInfo *info)
 
709
int write_record(Session *session, Table *table,COPY_INFO *info)
746
710
{
747
711
  int error;
748
 
  std::vector<unsigned char> key;
749
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
 
712
  char *key=0;
 
713
  MyBitmap *save_read_set, *save_write_set;
750
714
  uint64_t prev_insert_id= table->cursor->next_insert_id;
751
715
  uint64_t insert_id_for_cur_row= 0;
752
716
 
757
721
 
758
722
  if (info->handle_duplicates == DUP_REPLACE || info->handle_duplicates == DUP_UPDATE)
759
723
  {
760
 
    while ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
724
    while ((error=table->cursor->ha_write_row(table->record[0])))
761
725
    {
762
726
      uint32_t key_nr;
763
727
      /*
800
764
      */
801
765
      if (info->handle_duplicates == DUP_REPLACE &&
802
766
          table->next_number_field &&
803
 
          key_nr == table->getShare()->next_number_index &&
 
767
          key_nr == table->s->next_number_index &&
804
768
          (insert_id_for_cur_row > 0))
805
769
        goto err;
806
770
      if (table->cursor->getEngine()->check_flag(HTON_BIT_DUPLICATE_POS))
807
771
      {
808
 
        if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
772
        if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
809
773
          goto err;
810
774
      }
811
775
      else
816
780
          goto err;
817
781
        }
818
782
 
819
 
        if (not key.size())
 
783
        if (!key)
820
784
        {
821
 
          key.resize(table->getShare()->max_unique_length);
 
785
          if (!(key=(char*) malloc(table->s->max_unique_length)))
 
786
          {
 
787
            error=ENOMEM;
 
788
            goto err;
 
789
          }
822
790
        }
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,
 
791
        key_copy((unsigned char*) key,table->record[0],table->key_info+key_nr,0);
 
792
        if ((error=(table->cursor->index_read_idx_map(table->record[1],key_nr,
 
793
                                                    (unsigned char*) key, HA_WHOLE_KEY,
826
794
                                                    HA_READ_KEY_EXACT))))
827
795
          goto err;
828
796
      }
833
801
          that matches, is updated. If update causes a conflict again,
834
802
          an error is returned
835
803
        */
836
 
        assert(table->insert_values.size());
 
804
        assert(table->insert_values != NULL);
837
805
        table->storeRecordAsInsert();
838
806
        table->restoreRecord();
839
807
        assert(info->update_fields->elements ==
848
816
          table->cursor->adjust_next_insert_id_after_explicit_value(
849
817
            table->next_number_field->val_int());
850
818
        info->touched++;
851
 
 
852
 
        if (! table->records_are_comparable() || table->compare_records())
 
819
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
820
             !bitmap_is_subset(table->write_set, table->read_set)) ||
 
821
            table->compare_record())
853
822
        {
854
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
855
 
                                                table->getInsertRecord())) &&
 
823
          if ((error=table->cursor->ha_update_row(table->record[1],
 
824
                                                table->record[0])) &&
856
825
              error != HA_ERR_RECORD_IS_THE_SAME)
857
826
          {
858
827
            if (info->ignore &&
870
839
          /*
871
840
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
872
841
            like a regular UPDATE statement: it should not affect the value of a
873
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
842
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
874
843
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
875
844
            handled separately by Session::arg_of_last_insert_id_function.
876
845
          */
906
875
            (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
907
876
             table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
908
877
        {
909
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
910
 
                                                table->getInsertRecord())) &&
 
878
          if ((error=table->cursor->ha_update_row(table->record[1],
 
879
                                                table->record[0])) &&
911
880
              error != HA_ERR_RECORD_IS_THE_SAME)
912
881
            goto err;
913
882
          if (error != HA_ERR_RECORD_IS_THE_SAME)
923
892
        }
924
893
        else
925
894
        {
926
 
          if ((error=table->cursor->deleteRecord(table->getUpdateRecord())))
 
895
          if ((error=table->cursor->ha_delete_row(table->record[1])))
927
896
            goto err;
928
897
          info->deleted++;
929
898
          if (!table->cursor->has_transactions())
939
908
    */
940
909
    if (table->read_set != save_read_set ||
941
910
        table->write_set != save_write_set)
942
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
911
      table->column_bitmaps_set(save_read_set, save_write_set);
943
912
  }
944
 
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
913
  else if ((error=table->cursor->ha_write_row(table->record[0])))
945
914
  {
946
915
    if (!info->ignore ||
947
916
        table->cursor->is_fatal_error(error, HA_CHECK_DUP))
955
924
  session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
956
925
 
957
926
gok_or_after_err:
 
927
  if (key)
 
928
    free(key);
958
929
  if (!table->cursor->has_transactions())
959
930
    session->transaction.stmt.markModifiedNonTransData();
960
931
  return(0);
968
939
 
969
940
before_err:
970
941
  table->cursor->restore_auto_increment(prev_insert_id);
971
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
972
 
  return 1;
 
942
  if (key)
 
943
    free(key);
 
944
  table->column_bitmaps_set(save_read_set, save_write_set);
 
945
  return(1);
973
946
}
974
947
 
975
948
 
982
955
{
983
956
  int err= 0;
984
957
 
985
 
  for (Field **field=entry->getFields() ; *field ; field++)
 
958
  for (Field **field=entry->field ; *field ; field++)
986
959
  {
987
960
    if (((*field)->isWriteSet()) == false)
988
961
    {
1016
989
      }
1017
990
    }
1018
991
  }
1019
 
  return session->abortOnWarning() ? err : 0;
 
992
  return session->abort_on_warning ? err : 0;
1020
993
}
1021
994
 
1022
995
/***************************************************************************
1028
1001
  make insert specific preparation and checks after opening tables
1029
1002
 
1030
1003
  SYNOPSIS
1031
 
    insert_select_prepare()
 
1004
    mysql_insert_select_prepare()
1032
1005
    session         thread handler
1033
1006
 
1034
1007
  RETURN
1036
1009
    true  Error
1037
1010
*/
1038
1011
 
1039
 
bool insert_select_prepare(Session *session)
 
1012
bool mysql_insert_select_prepare(Session *session)
1040
1013
{
1041
1014
  LEX *lex= session->lex;
1042
1015
  Select_Lex *select_lex= &lex->select_lex;
1046
1019
    clause if table is VIEW
1047
1020
  */
1048
1021
 
1049
 
  if (prepare_insert(session, lex->query_tables,
 
1022
  if (mysql_prepare_insert(session, lex->query_tables,
1050
1023
                           lex->query_tables->table, lex->field_list, 0,
1051
1024
                           lex->update_list, lex->value_list,
1052
1025
                           lex->duplicates,
1070
1043
                             List<Item> *update_fields,
1071
1044
                             List<Item> *update_values,
1072
1045
                             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)
 
1046
                             bool ignore_check_option_errors)
 
1047
  :table_list(table_list_par), table(table_par), fields(fields_par),
 
1048
   autoinc_value_of_last_inserted_row(0),
 
1049
   insert_into_view(table_list_par && 0 != 0)
1077
1050
{
 
1051
  memset(&info, 0, sizeof(info));
1078
1052
  info.handle_duplicates= duplic;
1079
1053
  info.ignore= ignore_check_option_errors;
1080
1054
  info.update_fields= update_fields;
1105
1079
 
1106
1080
  if (!res && fields->elements)
1107
1081
  {
1108
 
    bool saved_abort_on_warning= session->abortOnWarning();
1109
 
    session->setAbortOnWarning(not info.ignore);
 
1082
    bool saved_abort_on_warning= session->abort_on_warning;
 
1083
    session->abort_on_warning= !info.ignore;
1110
1084
    res= check_that_all_fields_are_given_values(session, table_list->table,
1111
1085
                                                table_list);
1112
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1086
    session->abort_on_warning= saved_abort_on_warning;
1113
1087
  }
1114
1088
 
1115
1089
  if (info.handle_duplicates == DUP_UPDATE && !res)
1202
1176
  table->next_number_field=table->found_next_number_field;
1203
1177
 
1204
1178
  session->cuted_fields=0;
1205
 
 
1206
1179
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1207
1180
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1208
 
 
1209
1181
  if (info.handle_duplicates == DUP_REPLACE)
1210
1182
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1211
 
 
1212
1183
  if (info.handle_duplicates == DUP_UPDATE)
1213
1184
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1214
 
 
1215
 
  session->setAbortOnWarning(not info.ignore);
 
1185
  session->abort_on_warning= !info.ignore;
1216
1186
  table->mark_columns_needed_for_insert();
1217
1187
 
1218
1188
 
1261
1231
    table->cursor->ha_reset();
1262
1232
  }
1263
1233
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1264
 
  session->setAbortOnWarning(false);
 
1234
  session->abort_on_warning= 0;
1265
1235
  return;
1266
1236
}
1267
1237
 
1274
1244
  if (unit->offset_limit_cnt)
1275
1245
  {                                             // using limit offset,count
1276
1246
    unit->offset_limit_cnt--;
1277
 
    return false;
 
1247
    return(0);
1278
1248
  }
1279
1249
 
1280
1250
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1281
1251
  store_values(values);
1282
1252
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1283
1253
  if (session->is_error())
1284
 
    return true;
 
1254
    return(1);
1285
1255
 
1286
1256
  // Release latches in case bulk insert takes a long time
1287
1257
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1288
1258
 
1289
1259
  error= write_record(session, table, &info);
1290
 
  table->auto_increment_field_not_null= false;
1291
1260
 
1292
1261
  if (!error)
1293
1262
  {
1328
1297
  if (fields->elements)
1329
1298
    fill_record(session, *fields, values, true);
1330
1299
  else
1331
 
    fill_record(session, table->getFields(), values, true);
 
1300
    fill_record(session, table->field, values, true);
1332
1301
}
1333
1302
 
1334
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1303
void select_insert::send_error(uint32_t errcode,const char *err)
1335
1304
{
 
1305
 
 
1306
 
1336
1307
  my_message(errcode, err, MYF(0));
 
1308
 
 
1309
  return;
1337
1310
}
1338
1311
 
1339
1312
 
1352
1325
  {
1353
1326
    /*
1354
1327
      We must invalidate the table in the query cache before binlog writing
1355
 
      and autocommitOrRollback.
 
1328
      and ha_autocommit_or_rollback.
1356
1329
    */
1357
1330
    if (session->transaction.stmt.hasModifiedNonTransData())
1358
1331
      session->transaction.all.markModifiedNonTransData();
1370
1343
  }
1371
1344
  char buff[160];
1372
1345
  if (info.ignore)
1373
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1346
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1374
1347
            (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
1375
1348
  else
1376
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1349
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1377
1350
            (ulong) (info.deleted+info.updated), (ulong) session->cuted_fields);
1378
1351
  session->row_count_func= info.copied + info.deleted + info.updated;
1379
1352
 
1382
1355
    (session->arg_of_last_insert_id_function ?
1383
1356
     session->first_successful_insert_id_in_prev_stmt :
1384
1357
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1385
 
  session->my_ok((ulong) session->rowCount(),
 
1358
  session->my_ok((ulong) session->row_count_func,
1386
1359
                 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());
 
1360
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1389
1361
  return 0;
1390
1362
}
1391
1363
 
1454
1426
      items        in     List of items which should be used to produce rest
1455
1427
                          of fields for the table (corresponding fields will
1456
1428
                          be added to the end of alter_info->create_list)
1457
 
      lock         out    Pointer to the DrizzleLock object for table created
 
1429
      lock         out    Pointer to the DRIZZLE_LOCK object for table created
1458
1430
                          (or open temporary table) will be returned in this
1459
1431
                          parameter. Since this table is not included in
1460
1432
                          Session::lock caller is responsible for explicitly
1482
1454
 
1483
1455
static Table *create_table_from_items(Session *session, HA_CREATE_INFO *create_info,
1484
1456
                                      TableList *create_table,
1485
 
                                      message::Table &table_proto,
 
1457
                                      message::Table *table_proto,
1486
1458
                                      AlterInfo *alter_info,
1487
1459
                                      List<Item> *items,
1488
1460
                                      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;
1498
 
 
1499
 
  if (not (identifier.isTmp()) && create_table->table->db_stat)
 
1471
  bool not_used;
 
1472
 
 
1473
  bool lex_identified_temp_table= (table_proto->type() == message::Table::TEMPORARY);
 
1474
 
 
1475
  if (!(lex_identified_temp_table) &&
 
1476
      create_table->table->db_stat)
1500
1477
  {
1501
1478
    /* Table already exists and was open at openTablesLock() stage. */
1502
1479
    if (is_if_not_exists)
1504
1481
      create_info->table_existed= 1;            // Mark that table existed
1505
1482
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1506
1483
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1507
 
                          create_table->getTableName());
 
1484
                          create_table->table_name);
1508
1485
      return create_table->table;
1509
1486
    }
1510
1487
 
1511
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1488
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1512
1489
    return NULL;
1513
1490
  }
1514
1491
 
 
1492
  tmp_table.alias= 0;
 
1493
  tmp_table.timestamp_field= 0;
 
1494
  tmp_table.s= &share;
 
1495
 
 
1496
  tmp_table.s->db_create_options=0;
 
1497
  tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1498
  tmp_table.s->db_low_byte_first=
 
1499
        test(create_info->db_type == myisam_engine ||
 
1500
             create_info->db_type == heap_engine);
 
1501
  tmp_table.null_row= false;
 
1502
  tmp_table.maybe_null= false;
 
1503
 
 
1504
  while ((item=it++))
1515
1505
  {
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
 
      }
 
1506
    CreateField *cr_field;
 
1507
    Field *field, *def_field;
 
1508
    if (item->type() == Item::FUNC_ITEM)
 
1509
      if (item->result_type() != STRING_RESULT)
 
1510
        field= item->tmp_table_field(&tmp_table);
1540
1511
      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
 
    }
 
1512
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1513
    else
 
1514
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1515
                              (Item ***) 0, &tmp_field, &def_field, false,
 
1516
                              false, false, 0);
 
1517
    if (!field ||
 
1518
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1519
                                           ((Item_field *)item)->field :
 
1520
                                           (Field*) 0))))
 
1521
      return NULL;
 
1522
    if (item->maybe_null)
 
1523
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1524
    alter_info->create_list.push_back(cr_field);
1562
1525
  }
1563
1526
 
 
1527
  TableIdentifier identifier(create_table->db,
 
1528
                             create_table->table_name,
 
1529
                             lex_identified_temp_table ?  TEMP_TABLE :
 
1530
                             NO_TMP_TABLE);
 
1531
 
 
1532
 
1564
1533
  /*
1565
1534
    Create and lock table.
1566
1535
 
1568
1537
    creating base table on which name we have exclusive lock. So code below
1569
1538
    should not cause deadlocks or races.
1570
1539
  */
1571
 
  Table *table= 0;
1572
1540
  {
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))
 
1541
    if (!mysql_create_table_no_lock(session,
 
1542
                                    identifier,
 
1543
                                    create_info,
 
1544
                                    table_proto,
 
1545
                                    alter_info,
 
1546
                                    false,
 
1547
                                    select_field_count,
 
1548
                                    is_if_not_exists))
1581
1549
    {
1582
 
      if (create_info->table_existed && not identifier.isTmp())
 
1550
      if (create_info->table_existed &&
 
1551
          !(lex_identified_temp_table))
1583
1552
      {
1584
1553
        /*
1585
1554
          This means that someone created table underneath server
1586
1555
          or it was created via different mysqld front-end to the
1587
1556
          cluster. We don't have much options but throw an error.
1588
1557
        */
1589
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1558
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1590
1559
        return NULL;
1591
1560
      }
1592
1561
 
1593
 
      if (not identifier.isTmp())
 
1562
      if (!(lex_identified_temp_table))
1594
1563
      {
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)
 
1564
        pthread_mutex_lock(&LOCK_open); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1565
        if (session->reopen_name_locked_table(create_table, false))
1599
1566
        {
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
 
          }
 
1567
          quick_rm_table(*session, identifier);
1610
1568
        }
1611
1569
        else
1612
 
        {
1613
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
1614
 
        }
 
1570
          table= create_table->table;
 
1571
        pthread_mutex_unlock(&LOCK_open);
1615
1572
      }
1616
1573
      else
1617
1574
      {
1618
 
        if (not (table= session->openTable(create_table, (bool*) 0,
1619
 
                                           DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
1620
 
            not create_info->table_existed)
 
1575
        if (!(table= session->openTable(create_table, (bool*) 0,
 
1576
                                         DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
 
1577
            !create_info->table_existed)
1621
1578
        {
1622
1579
          /*
1623
1580
            This shouldn't happen as creation of temporary table should make
1624
1581
            it preparable for open. But let us do close_temporary_table() here
1625
1582
            just in case.
1626
1583
          */
1627
 
          session->drop_temporary_table(identifier);
 
1584
          session->drop_temporary_table(create_table);
1628
1585
        }
1629
1586
      }
1630
1587
    }
1631
 
    if (not table)                                   // open failed
 
1588
    if (!table)                                   // open failed
1632
1589
      return NULL;
1633
1590
  }
1634
1591
 
1635
1592
  table->reginfo.lock_type=TL_WRITE;
1636
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1593
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1594
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1637
1595
  {
1638
1596
    if (*lock)
1639
1597
    {
1640
 
      session->unlockTables(*lock);
 
1598
      mysql_unlock_tables(session, *lock);
1641
1599
      *lock= 0;
1642
1600
    }
1643
1601
 
1644
 
    if (not create_info->table_existed)
1645
 
      session->drop_open_table(table, identifier);
 
1602
    if (!create_info->table_existed)
 
1603
      session->drop_open_table(table, create_table->db, create_table->table_name);
1646
1604
    return NULL;
1647
1605
  }
1648
1606
 
1653
1611
int
1654
1612
select_create::prepare(List<Item> &values, Select_Lex_Unit *u)
1655
1613
{
1656
 
  DrizzleLock *extra_lock= NULL;
 
1614
  bool lex_identified_temp_table= (table_proto->type() == message::Table::TEMPORARY);
 
1615
 
 
1616
  DRIZZLE_LOCK *extra_lock= NULL;
1657
1617
  /*
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.
 
1618
    For row-based replication, the CREATE-SELECT statement is written
 
1619
    in two pieces: the first one contain the CREATE TABLE statement
 
1620
    necessary to create the table and the second part contain the rows
 
1621
    that should go into the table.
 
1622
 
 
1623
    For non-temporary tables, the start of the CREATE-SELECT
 
1624
    implicitly commits the previous transaction, and all events
 
1625
    forming the statement will be stored the transaction cache. At end
 
1626
    of the statement, the entire statement is committed as a
 
1627
    transaction, and all events are written to the binary log.
 
1628
 
 
1629
    On the master, the table is locked for the duration of the
 
1630
    statement, but since the CREATE part is replicated as a simple
 
1631
    statement, there is no way to lock the table for accesses on the
 
1632
    slave.  Hence, we have to hold on to the CREATE part of the
 
1633
    statement until the statement has finished.
1665
1634
   */
1666
1635
 
1667
1636
  unit= u;
1668
1637
 
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
 
  {
 
1638
  /*
 
1639
    Start a statement transaction before the create if we are using
 
1640
    row-based replication for the statement.  If we are creating a
 
1641
    temporary table, we need to start a statement transaction.
 
1642
  */
 
1643
 
 
1644
  if (!(table= create_table_from_items(session, create_info, create_table,
 
1645
                                       table_proto,
 
1646
                                       alter_info, &values,
 
1647
                                       is_if_not_exists,
 
1648
                                       &extra_lock)))
1675
1649
    return(-1);                         // abort() deletes table
1676
 
  }
1677
1650
 
1678
1651
  if (extra_lock)
1679
1652
  {
1680
1653
    assert(m_plock == NULL);
1681
1654
 
1682
 
    if (identifier.isTmp())
 
1655
    if (lex_identified_temp_table)
1683
1656
      m_plock= &m_lock;
1684
1657
    else
1685
1658
      m_plock= &session->extra_lock;
1687
1660
    *m_plock= extra_lock;
1688
1661
  }
1689
1662
 
1690
 
  if (table->getShare()->sizeFields() < values.elements)
 
1663
  if (table->s->fields < values.elements)
1691
1664
  {
1692
1665
    my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
1693
1666
    return(-1);
1694
1667
  }
1695
1668
 
1696
1669
 /* First field to copy */
1697
 
  field= table->getFields() + table->getShare()->sizeFields() - values.elements;
 
1670
  field= table->field+table->s->fields - values.elements;
1698
1671
 
1699
1672
  /* Mark all fields that are given values */
1700
1673
  for (Field **f= field ; *f ; f++)
1701
 
  {
1702
 
    table->setWriteSet((*f)->position());
1703
 
  }
 
1674
    table->setWriteSet((*f)->field_index);
1704
1675
 
1705
1676
  /* Don't set timestamp if used */
1706
1677
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1710
1681
  session->cuted_fields=0;
1711
1682
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1712
1683
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1713
 
 
1714
1684
  if (info.handle_duplicates == DUP_REPLACE)
1715
1685
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1716
 
 
1717
1686
  if (info.handle_duplicates == DUP_UPDATE)
1718
1687
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1719
 
 
1720
1688
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1721
 
  session->setAbortOnWarning(not info.ignore);
 
1689
  session->abort_on_warning= !info.ignore;
1722
1690
  if (check_that_all_fields_are_given_values(session, table, table_list))
1723
1691
    return(1);
1724
 
 
1725
1692
  table->mark_columns_needed_for_insert();
1726
1693
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1727
1694
  return(0);
1733
1700
}
1734
1701
 
1735
1702
 
1736
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1703
void select_create::send_error(uint32_t errcode,const char *err)
1737
1704
{
1738
1705
  /*
1739
1706
    This will execute any rollbacks that are necessary before writing
1747
1714
 
1748
1715
  */
1749
1716
  select_insert::send_error(errcode, err);
 
1717
 
 
1718
  return;
1750
1719
}
1751
1720
 
1752
1721
 
1762
1731
      tables.  This can fail, but we should unlock the table
1763
1732
      nevertheless.
1764
1733
    */
1765
 
    if (!table->getShare()->getType())
 
1734
    if (!table->s->tmp_table)
1766
1735
    {
1767
1736
      TransactionServices &transaction_services= TransactionServices::singleton();
1768
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1737
      transaction_services.ha_autocommit_or_rollback(session, 0);
1769
1738
      (void) session->endActiveTransaction();
1770
1739
    }
1771
1740
 
1773
1742
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1774
1743
    if (m_plock)
1775
1744
    {
1776
 
      session->unlockTables(*m_plock);
 
1745
      mysql_unlock_tables(session, *m_plock);
1777
1746
      *m_plock= NULL;
1778
1747
      m_plock= NULL;
1779
1748
    }
1803
1772
 
1804
1773
  if (m_plock)
1805
1774
  {
1806
 
    session->unlockTables(*m_plock);
 
1775
    mysql_unlock_tables(session, *m_plock);
1807
1776
    *m_plock= NULL;
1808
1777
    m_plock= NULL;
1809
1778
  }
1812
1781
  {
1813
1782
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1814
1783
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1815
 
    if (not create_info->table_existed)
1816
 
      session->drop_open_table(table, identifier);
 
1784
    if (!create_info->table_existed)
 
1785
      session->drop_open_table(table, create_table->db, create_table->table_name);
1817
1786
    table= NULL;                                    // Safety
1818
1787
  }
1819
1788
}