~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

Fixed the clock_gettime test.

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>
29
28
#include <drizzled/lock.h>
30
29
#include "drizzled/sql_table.h"
31
30
#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
 
{
 
31
 
 
32
using namespace drizzled;
39
33
 
40
34
extern plugin::StorageEngine *heap_engine;
41
35
extern plugin::StorageEngine *myisam_engine;
70
64
 
71
65
  if (fields.elements == 0 && values.elements != 0)
72
66
  {
73
 
    if (values.elements != table->getShare()->sizeFields())
 
67
    if (values.elements != table->s->fields)
74
68
    {
75
69
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
76
70
      return -1;
123
117
    if (table->timestamp_field) // Don't automaticly set timestamp if used
124
118
    {
125
119
      if (table->timestamp_field->isWriteSet())
126
 
      {
127
120
        clear_timestamp_auto_bits(table->timestamp_field_type,
128
121
                                  TIMESTAMP_AUTO_SET_ON_INSERT);
129
 
      }
130
122
      else
131
123
      {
132
 
        table->setWriteSet(table->timestamp_field->position());
 
124
        table->setWriteSet(table->timestamp_field->field_index);
133
125
      }
134
126
    }
135
127
  }
170
162
      Unmark the timestamp field so that we can check if this is modified
171
163
      by update_fields
172
164
    */
173
 
    timestamp_mark= table->write_set->test(table->timestamp_field->position());
174
 
    table->write_set->reset(table->timestamp_field->position());
 
165
    timestamp_mark= table->write_set->testAndClear(table->timestamp_field->field_index);
175
166
  }
176
167
 
177
168
  /* Check the fields we are going to modify */
182
173
  {
183
174
    /* Don't set timestamp column if this is modified. */
184
175
    if (table->timestamp_field->isWriteSet())
185
 
    {
186
176
      clear_timestamp_auto_bits(table->timestamp_field_type,
187
177
                                TIMESTAMP_AUTO_SET_ON_UPDATE);
188
 
    }
189
 
 
190
178
    if (timestamp_mark)
191
 
    {
192
 
      table->setWriteSet(table->timestamp_field->position());
193
 
    }
 
179
      table->setWriteSet(table->timestamp_field->field_index);
194
180
  }
195
181
  return 0;
196
182
}
241
227
  uint32_t value_count;
242
228
  ulong counter = 1;
243
229
  uint64_t id;
244
 
  CopyInfo info;
 
230
  COPY_INFO info;
245
231
  Table *table= 0;
246
232
  List_iterator_fast<List_item> its(values_list);
247
233
  List_item *values;
276
262
                           false,
277
263
                           (fields.elements || !value_count ||
278
264
                            (0) != 0), !ignore))
279
 
  {
280
 
    if (table != NULL)
281
 
      table->cursor->ha_release_auto_increment();
282
 
    if (!joins_freed)
283
 
      free_underlaid_joins(session, &session->lex->select_lex);
284
 
    session->abort_on_warning= 0;
285
 
    DRIZZLE_INSERT_DONE(1, 0);
286
 
    return true;
287
 
  }
 
265
    goto abort;
288
266
 
289
267
  /* mysql_prepare_insert set table_list->table if it was not set */
290
268
  table= table_list->table;
315
293
    if (values->elements != value_count)
316
294
    {
317
295
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
318
 
 
319
 
      if (table != NULL)
320
 
        table->cursor->ha_release_auto_increment();
321
 
      if (!joins_freed)
322
 
        free_underlaid_joins(session, &session->lex->select_lex);
323
 
      session->abort_on_warning= 0;
324
 
      DRIZZLE_INSERT_DONE(1, 0);
325
 
 
326
 
      return true;
 
296
      goto abort;
327
297
    }
328
298
    if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
329
 
    {
330
 
      if (table != NULL)
331
 
        table->cursor->ha_release_auto_increment();
332
 
      if (!joins_freed)
333
 
        free_underlaid_joins(session, &session->lex->select_lex);
334
 
      session->abort_on_warning= 0;
335
 
      DRIZZLE_INSERT_DONE(1, 0);
336
 
      return true;
337
 
    }
 
299
      goto abort;
338
300
  }
339
301
  its.rewind ();
340
302
 
344
306
  /*
345
307
    Fill in the given fields and dump it to the table cursor
346
308
  */
 
309
  memset(&info, 0, sizeof(info));
347
310
  info.ignore= ignore;
348
311
  info.handle_duplicates=duplic;
349
312
  info.update_fields= &update_fields;
354
317
    For single line insert, generate an error if try to set a NOT NULL field
355
318
    to NULL.
356
319
  */
357
 
  session->count_cuted_fields= ignore ? CHECK_FIELD_WARN : CHECK_FIELD_ERROR_FOR_NULL;
358
 
 
 
320
  session->count_cuted_fields= ((values_list.elements == 1 &&
 
321
                                 !ignore) ?
 
322
                                CHECK_FIELD_ERROR_FOR_NULL :
 
323
                                CHECK_FIELD_WARN);
359
324
  session->cuted_fields = 0L;
360
325
  table->next_number_field=table->found_next_number_field;
361
326
 
401
366
    {
402
367
      table->restoreRecordAsDefault();  // Get empty record
403
368
 
404
 
      if (fill_record(session, table->getFields(), *values))
 
369
      if (fill_record(session, table->field, *values))
405
370
      {
406
371
        if (values_list.elements != 1 && ! session->is_error())
407
372
        {
414
379
    }
415
380
 
416
381
    // Release latches in case bulk insert takes a long time
417
 
    plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
382
    plugin::StorageEngine::releaseTemporaryLatches(session);
418
383
 
419
384
    error=write_record(session, table ,&info);
420
385
    if (error)
446
411
    transactional_table= table->cursor->has_transactions();
447
412
 
448
413
    changed= (info.copied || info.deleted || info.updated);
449
 
    if ((changed && error <= 0) || session->transaction.stmt.hasModifiedNonTransData())
 
414
    if ((changed && error <= 0) || session->transaction.stmt.modified_non_trans_table)
450
415
    {
451
 
      if (session->transaction.stmt.hasModifiedNonTransData())
452
 
        session->transaction.all.markModifiedNonTransData();
 
416
      if (session->transaction.stmt.modified_non_trans_table)
 
417
        session->transaction.all.modified_non_trans_table= true;
453
418
    }
454
 
    assert(transactional_table || !changed || session->transaction.stmt.hasModifiedNonTransData());
 
419
    assert(transactional_table || !changed || session->transaction.stmt.modified_non_trans_table);
455
420
 
456
421
  }
457
422
  session->set_proc_info("end");
478
443
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
479
444
 
480
445
  if (error)
481
 
  {
482
 
    if (table != NULL)
483
 
      table->cursor->ha_release_auto_increment();
484
 
    if (!joins_freed)
485
 
      free_underlaid_joins(session, &session->lex->select_lex);
486
 
    session->abort_on_warning= 0;
487
 
    DRIZZLE_INSERT_DONE(1, 0);
488
 
    return true;
489
 
  }
490
 
 
 
446
    goto abort;
491
447
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
492
448
                                    !session->cuted_fields))
493
449
  {
499
455
  {
500
456
    char buff[160];
501
457
    if (ignore)
502
 
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
458
      sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
503
459
              (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
504
460
    else
505
 
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
461
      sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
506
462
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
507
463
    session->row_count_func= info.copied + info.deleted + info.updated;
508
464
    session->my_ok((ulong) session->row_count_func,
509
465
                   info.copied + info.deleted + info.touched, id, buff);
510
466
  }
511
 
  session->status_var.inserted_row_count+= session->row_count_func;
512
467
  session->abort_on_warning= 0;
513
468
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
514
 
 
515
469
  return false;
 
470
 
 
471
abort:
 
472
  if (table != NULL)
 
473
    table->cursor->ha_release_auto_increment();
 
474
  if (!joins_freed)
 
475
    free_underlaid_joins(session, &session->lex->select_lex);
 
476
  session->abort_on_warning= 0;
 
477
  DRIZZLE_INSERT_DONE(1, 0);
 
478
  return true;
516
479
}
517
480
 
518
481
 
706
669
 
707
670
static int last_uniq_key(Table *table,uint32_t keynr)
708
671
{
709
 
  while (++keynr < table->getShare()->sizeKeys())
 
672
  while (++keynr < table->s->keys)
710
673
    if (table->key_info[keynr].flags & HA_NOSAME)
711
674
      return 0;
712
675
  return 1;
721
684
     write_record()
722
685
      session   - thread context
723
686
      table - table to which record should be written
724
 
      info  - CopyInfo structure describing handling of duplicates
 
687
      info  - COPY_INFO structure describing handling of duplicates
725
688
              and which is used for counting number of records inserted
726
689
              and deleted.
727
690
 
731
694
    then both on update triggers will work instead. Similarly both on
732
695
    delete triggers will be invoked if we will delete conflicting records.
733
696
 
734
 
    Sets session->transaction.stmt.modified_non_trans_data to true if table which is updated didn't have
 
697
    Sets session->transaction.stmt.modified_non_trans_table to true if table which is updated didn't have
735
698
    transactions.
736
699
 
737
700
  RETURN VALUE
740
703
*/
741
704
 
742
705
 
743
 
int write_record(Session *session, Table *table,CopyInfo *info)
 
706
int write_record(Session *session, Table *table,COPY_INFO *info)
744
707
{
745
708
  int error;
746
 
  std::vector<unsigned char> key;
747
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
 
709
  char *key=0;
 
710
  MyBitmap *save_read_set, *save_write_set;
748
711
  uint64_t prev_insert_id= table->cursor->next_insert_id;
749
712
  uint64_t insert_id_for_cur_row= 0;
750
713
 
755
718
 
756
719
  if (info->handle_duplicates == DUP_REPLACE || info->handle_duplicates == DUP_UPDATE)
757
720
  {
758
 
    while ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
721
    while ((error=table->cursor->ha_write_row(table->record[0])))
759
722
    {
760
723
      uint32_t key_nr;
761
724
      /*
798
761
      */
799
762
      if (info->handle_duplicates == DUP_REPLACE &&
800
763
          table->next_number_field &&
801
 
          key_nr == table->getShare()->next_number_index &&
 
764
          key_nr == table->s->next_number_index &&
802
765
          (insert_id_for_cur_row > 0))
803
766
        goto err;
804
767
      if (table->cursor->getEngine()->check_flag(HTON_BIT_DUPLICATE_POS))
805
768
      {
806
 
        if (table->cursor->rnd_pos(table->getUpdateRecord(),table->cursor->dup_ref))
 
769
        if (table->cursor->rnd_pos(table->record[1],table->cursor->dup_ref))
807
770
          goto err;
808
771
      }
809
772
      else
814
777
          goto err;
815
778
        }
816
779
 
817
 
        if (not key.size())
 
780
        if (!key)
818
781
        {
819
 
          key.resize(table->getShare()->max_unique_length);
 
782
          if (!(key=(char*) malloc(table->s->max_unique_length)))
 
783
          {
 
784
            error=ENOMEM;
 
785
            goto err;
 
786
          }
820
787
        }
821
 
        key_copy(&key[0], table->getInsertRecord(), table->key_info+key_nr, 0);
822
 
        if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
823
 
                                                    &key[0], HA_WHOLE_KEY,
 
788
        key_copy((unsigned char*) key,table->record[0],table->key_info+key_nr,0);
 
789
        if ((error=(table->cursor->index_read_idx_map(table->record[1],key_nr,
 
790
                                                    (unsigned char*) key, HA_WHOLE_KEY,
824
791
                                                    HA_READ_KEY_EXACT))))
825
792
          goto err;
826
793
      }
831
798
          that matches, is updated. If update causes a conflict again,
832
799
          an error is returned
833
800
        */
834
 
        assert(table->insert_values.size());
 
801
        assert(table->insert_values != NULL);
835
802
        table->storeRecordAsInsert();
836
803
        table->restoreRecord();
837
804
        assert(info->update_fields->elements ==
846
813
          table->cursor->adjust_next_insert_id_after_explicit_value(
847
814
            table->next_number_field->val_int());
848
815
        info->touched++;
849
 
 
850
 
        if (! table->records_are_comparable() || table->compare_records())
 
816
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
817
             !bitmap_is_subset(table->write_set, table->read_set)) ||
 
818
            table->compare_record())
851
819
        {
852
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
853
 
                                                table->getInsertRecord())) &&
 
820
          if ((error=table->cursor->ha_update_row(table->record[1],
 
821
                                                table->record[0])) &&
854
822
              error != HA_ERR_RECORD_IS_THE_SAME)
855
823
          {
856
824
            if (info->ignore &&
904
872
            (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
905
873
             table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
906
874
        {
907
 
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
908
 
                                                table->getInsertRecord())) &&
 
875
          if ((error=table->cursor->ha_update_row(table->record[1],
 
876
                                                table->record[0])) &&
909
877
              error != HA_ERR_RECORD_IS_THE_SAME)
910
878
            goto err;
911
879
          if (error != HA_ERR_RECORD_IS_THE_SAME)
921
889
        }
922
890
        else
923
891
        {
924
 
          if ((error=table->cursor->deleteRecord(table->getUpdateRecord())))
 
892
          if ((error=table->cursor->ha_delete_row(table->record[1])))
925
893
            goto err;
926
894
          info->deleted++;
927
895
          if (!table->cursor->has_transactions())
928
 
            session->transaction.stmt.markModifiedNonTransData();
 
896
            session->transaction.stmt.modified_non_trans_table= true;
929
897
          /* Let us attempt do write_row() once more */
930
898
        }
931
899
      }
937
905
    */
938
906
    if (table->read_set != save_read_set ||
939
907
        table->write_set != save_write_set)
940
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
908
      table->column_bitmaps_set(save_read_set, save_write_set);
941
909
  }
942
 
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
 
910
  else if ((error=table->cursor->ha_write_row(table->record[0])))
943
911
  {
944
912
    if (!info->ignore ||
945
913
        table->cursor->is_fatal_error(error, HA_CHECK_DUP))
953
921
  session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
954
922
 
955
923
gok_or_after_err:
 
924
  if (key)
 
925
    free(key);
956
926
  if (!table->cursor->has_transactions())
957
 
    session->transaction.stmt.markModifiedNonTransData();
 
927
    session->transaction.stmt.modified_non_trans_table= true;
958
928
  return(0);
959
929
 
960
930
err:
966
936
 
967
937
before_err:
968
938
  table->cursor->restore_auto_increment(prev_insert_id);
969
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
970
 
  return 1;
 
939
  if (key)
 
940
    free(key);
 
941
  table->column_bitmaps_set(save_read_set, save_write_set);
 
942
  return(1);
971
943
}
972
944
 
973
945
 
980
952
{
981
953
  int err= 0;
982
954
 
983
 
  for (Field **field=entry->getFields() ; *field ; field++)
 
955
  for (Field **field=entry->field ; *field ; field++)
984
956
  {
985
957
    if (((*field)->isWriteSet()) == false)
986
958
    {
1068
1040
                             List<Item> *update_fields,
1069
1041
                             List<Item> *update_values,
1070
1042
                             enum_duplicates duplic,
1071
 
                             bool ignore_check_option_errors) :
1072
 
  table_list(table_list_par), table(table_par), fields(fields_par),
1073
 
  autoinc_value_of_last_inserted_row(0),
1074
 
  insert_into_view(table_list_par && 0 != 0)
 
1043
                             bool ignore_check_option_errors)
 
1044
  :table_list(table_list_par), table(table_par), fields(fields_par),
 
1045
   autoinc_value_of_last_inserted_row(0),
 
1046
   insert_into_view(table_list_par && 0 != 0)
1075
1047
{
 
1048
  memset(&info, 0, sizeof(info));
1076
1049
  info.handle_duplicates= duplic;
1077
1050
  info.ignore= ignore_check_option_errors;
1078
1051
  info.update_fields= update_fields;
1278
1251
    return(1);
1279
1252
 
1280
1253
  // Release latches in case bulk insert takes a long time
1281
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1254
  plugin::StorageEngine::releaseTemporaryLatches(session);
1282
1255
 
1283
1256
  error= write_record(session, table, &info);
1284
 
  table->auto_increment_field_not_null= false;
1285
1257
 
1286
1258
  if (!error)
1287
1259
  {
1322
1294
  if (fields->elements)
1323
1295
    fill_record(session, *fields, values, true);
1324
1296
  else
1325
 
    fill_record(session, table->getFields(), values, true);
 
1297
    fill_record(session, table->field, values, true);
1326
1298
}
1327
1299
 
1328
1300
void select_insert::send_error(uint32_t errcode,const char *err)
1350
1322
  {
1351
1323
    /*
1352
1324
      We must invalidate the table in the query cache before binlog writing
1353
 
      and autocommitOrRollback.
 
1325
      and ha_autocommit_or_rollback.
1354
1326
    */
1355
 
    if (session->transaction.stmt.hasModifiedNonTransData())
1356
 
      session->transaction.all.markModifiedNonTransData();
 
1327
    if (session->transaction.stmt.modified_non_trans_table)
 
1328
      session->transaction.all.modified_non_trans_table= true;
1357
1329
  }
1358
1330
  assert(trans_table || !changed ||
1359
 
              session->transaction.stmt.hasModifiedNonTransData());
 
1331
              session->transaction.stmt.modified_non_trans_table);
1360
1332
 
1361
1333
  table->cursor->ha_release_auto_increment();
1362
1334
 
1368
1340
  }
1369
1341
  char buff[160];
1370
1342
  if (info.ignore)
1371
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1343
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1372
1344
            (ulong) (info.records - info.copied), (ulong) session->cuted_fields);
1373
1345
  else
1374
 
    snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
 
1346
    sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1375
1347
            (ulong) (info.deleted+info.updated), (ulong) session->cuted_fields);
1376
1348
  session->row_count_func= info.copied + info.deleted + info.updated;
1377
1349
 
1382
1354
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1383
1355
  session->my_ok((ulong) session->row_count_func,
1384
1356
                 info.copied + info.deleted + info.touched, id, buff);
1385
 
  session->status_var.inserted_row_count+= session->row_count_func; 
1386
1357
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1387
1358
  return 0;
1388
1359
}
1419
1390
    changed= (info.copied || info.deleted || info.updated);
1420
1391
    transactional_table= table->cursor->has_transactions();
1421
1392
    assert(transactional_table || !changed ||
1422
 
                session->transaction.stmt.hasModifiedNonTransData());
 
1393
                session->transaction.stmt.modified_non_trans_table);
1423
1394
    table->cursor->ha_release_auto_increment();
1424
1395
  }
1425
1396
 
1452
1423
      items        in     List of items which should be used to produce rest
1453
1424
                          of fields for the table (corresponding fields will
1454
1425
                          be added to the end of alter_info->create_list)
1455
 
      lock         out    Pointer to the DrizzleLock object for table created
 
1426
      lock         out    Pointer to the DRIZZLE_LOCK object for table created
1456
1427
                          (or open temporary table) will be returned in this
1457
1428
                          parameter. Since this table is not included in
1458
1429
                          Session::lock caller is responsible for explicitly
1480
1451
 
1481
1452
static Table *create_table_from_items(Session *session, HA_CREATE_INFO *create_info,
1482
1453
                                      TableList *create_table,
1483
 
                                      message::Table &table_proto,
 
1454
                                      message::Table *table_proto,
1484
1455
                                      AlterInfo *alter_info,
1485
1456
                                      List<Item> *items,
1486
1457
                                      bool is_if_not_exists,
1487
 
                                      DrizzleLock **lock,
1488
 
                                      TableIdentifier &identifier)
 
1458
                                      DRIZZLE_LOCK **lock)
1489
1459
{
1490
 
  TableShare share(message::Table::INTERNAL);
 
1460
  Table tmp_table;              // Used during 'CreateField()'
 
1461
  TableShare share;
 
1462
  Table *table= 0;
1491
1463
  uint32_t select_field_count= items->elements;
1492
1464
  /* Add selected items to field list */
1493
1465
  List_iterator_fast<Item> it(*items);
1495
1467
  Field *tmp_field;
1496
1468
  bool not_used;
1497
1469
 
1498
 
  if (not (identifier.isTmp()) && create_table->table->db_stat)
 
1470
  bool lex_identified_temp_table= (table_proto->type() == drizzled::message::Table::TEMPORARY);
 
1471
 
 
1472
  if (!(lex_identified_temp_table) &&
 
1473
      create_table->table->db_stat)
1499
1474
  {
1500
1475
    /* Table already exists and was open at openTablesLock() stage. */
1501
1476
    if (is_if_not_exists)
1503
1478
      create_info->table_existed= 1;            // Mark that table existed
1504
1479
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1505
1480
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1506
 
                          create_table->getTableName());
 
1481
                          create_table->table_name);
1507
1482
      return create_table->table;
1508
1483
    }
1509
1484
 
1510
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1485
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1511
1486
    return NULL;
1512
1487
  }
1513
1488
 
 
1489
  tmp_table.alias= 0;
 
1490
  tmp_table.timestamp_field= 0;
 
1491
  tmp_table.s= &share;
 
1492
 
 
1493
  tmp_table.s->db_create_options=0;
 
1494
  tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1495
  tmp_table.s->db_low_byte_first=
 
1496
        test(create_info->db_type == myisam_engine ||
 
1497
             create_info->db_type == heap_engine);
 
1498
  tmp_table.null_row= false;
 
1499
  tmp_table.maybe_null= false;
 
1500
 
 
1501
  while ((item=it++))
1514
1502
  {
1515
 
    table::Shell tmp_table(share);              // Used during 'CreateField()'
1516
 
    tmp_table.timestamp_field= 0;
1517
 
 
1518
 
    tmp_table.getMutableShare()->db_create_options= 0;
1519
 
    tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1520
 
 
1521
 
    if (not table_proto.engine().name().compare("MyISAM"))
1522
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1523
 
    else if (not table_proto.engine().name().compare("MEMORY"))
1524
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1525
 
 
1526
 
    tmp_table.null_row= false;
1527
 
    tmp_table.maybe_null= false;
1528
 
 
1529
 
    tmp_table.in_use= session;
1530
 
 
1531
 
    while ((item=it++))
1532
 
    {
1533
 
      CreateField *cr_field;
1534
 
      Field *field, *def_field;
1535
 
      if (item->type() == Item::FUNC_ITEM)
1536
 
      {
1537
 
        if (item->result_type() != STRING_RESULT)
1538
 
        {
1539
 
          field= item->tmp_table_field(&tmp_table);
1540
 
        }
1541
 
        else
1542
 
        {
1543
 
          field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1544
 
        }
1545
 
      }
 
1503
    CreateField *cr_field;
 
1504
    Field *field, *def_field;
 
1505
    if (item->type() == Item::FUNC_ITEM)
 
1506
      if (item->result_type() != STRING_RESULT)
 
1507
        field= item->tmp_table_field(&tmp_table);
1546
1508
      else
1547
 
      {
1548
 
        field= create_tmp_field(session, &tmp_table, item, item->type(),
1549
 
                                (Item ***) 0, &tmp_field, &def_field, false,
1550
 
                                false, false, 0);
1551
 
      }
1552
 
 
1553
 
      if (!field ||
1554
 
          !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1555
 
                                            ((Item_field *)item)->field :
1556
 
                                            (Field*) 0))))
1557
 
      {
1558
 
        return NULL;
1559
 
      }
1560
 
 
1561
 
      if (item->maybe_null)
1562
 
      {
1563
 
        cr_field->flags &= ~NOT_NULL_FLAG;
1564
 
      }
1565
 
 
1566
 
      alter_info->create_list.push_back(cr_field);
1567
 
    }
 
1509
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1510
    else
 
1511
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1512
                              (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
 
1513
                              0);
 
1514
    if (!field ||
 
1515
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1516
                                           ((Item_field *)item)->field :
 
1517
                                           (Field*) 0))))
 
1518
      return NULL;
 
1519
    if (item->maybe_null)
 
1520
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1521
    alter_info->create_list.push_back(cr_field);
1568
1522
  }
1569
1523
 
 
1524
  TableIdentifier identifier(create_table->db,
 
1525
                             create_table->table_name,
 
1526
                             lex_identified_temp_table ?  TEMP_TABLE :
 
1527
                             NO_TMP_TABLE);
 
1528
 
 
1529
 
1570
1530
  /*
1571
1531
    Create and lock table.
1572
1532
 
1574
1534
    creating base table on which name we have exclusive lock. So code below
1575
1535
    should not cause deadlocks or races.
1576
1536
  */
1577
 
  Table *table= 0;
1578
1537
  {
1579
 
    if (not mysql_create_table_no_lock(session,
1580
 
                                       identifier,
1581
 
                                       create_info,
1582
 
                                       table_proto,
1583
 
                                       alter_info,
1584
 
                                       false,
1585
 
                                       select_field_count,
1586
 
                                       is_if_not_exists))
 
1538
    if (!mysql_create_table_no_lock(session,
 
1539
                                    identifier,
 
1540
                                    create_info,
 
1541
                                    table_proto,
 
1542
                                    alter_info,
 
1543
                                    false,
 
1544
                                    select_field_count,
 
1545
                                    is_if_not_exists))
1587
1546
    {
1588
 
      if (create_info->table_existed && not identifier.isTmp())
 
1547
      if (create_info->table_existed &&
 
1548
          !(lex_identified_temp_table))
1589
1549
      {
1590
1550
        /*
1591
1551
          This means that someone created table underneath server
1592
1552
          or it was created via different mysqld front-end to the
1593
1553
          cluster. We don't have much options but throw an error.
1594
1554
        */
1595
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1555
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1596
1556
        return NULL;
1597
1557
      }
1598
1558
 
1599
 
      if (not identifier.isTmp())
 
1559
      if (!(lex_identified_temp_table))
1600
1560
      {
1601
 
        /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1602
 
        boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1603
 
 
1604
 
        if (create_table->table)
 
1561
        pthread_mutex_lock(&LOCK_open); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1562
        if (session->reopen_name_locked_table(create_table, false))
1605
1563
        {
1606
 
          table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1607
 
 
1608
 
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1609
 
          {
1610
 
            plugin::StorageEngine::dropTable(*session, identifier);
1611
 
          }
1612
 
          else
1613
 
          {
1614
 
            table= create_table->table;
1615
 
          }
 
1564
          quick_rm_table(*session, identifier);
1616
1565
        }
1617
1566
        else
1618
 
        {
1619
 
          plugin::StorageEngine::dropTable(*session, identifier);
1620
 
        }
 
1567
          table= create_table->table;
 
1568
        pthread_mutex_unlock(&LOCK_open);
1621
1569
      }
1622
1570
      else
1623
1571
      {
1624
 
        if (not (table= session->openTable(create_table, (bool*) 0,
1625
 
                                           DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
1626
 
            not create_info->table_existed)
 
1572
        if (!(table= session->openTable(create_table, (bool*) 0,
 
1573
                                         DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
 
1574
            !create_info->table_existed)
1627
1575
        {
1628
1576
          /*
1629
1577
            This shouldn't happen as creation of temporary table should make
1630
1578
            it preparable for open. But let us do close_temporary_table() here
1631
1579
            just in case.
1632
1580
          */
1633
 
          session->drop_temporary_table(identifier);
 
1581
          session->drop_temporary_table(create_table);
1634
1582
        }
1635
1583
      }
1636
1584
    }
1637
 
    if (not table)                                   // open failed
 
1585
    if (!table)                                   // open failed
1638
1586
      return NULL;
1639
1587
  }
1640
1588
 
1641
1589
  table->reginfo.lock_type=TL_WRITE;
1642
 
  if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
 
1590
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1591
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1643
1592
  {
1644
1593
    if (*lock)
1645
1594
    {
1646
 
      session->unlockTables(*lock);
 
1595
      mysql_unlock_tables(session, *lock);
1647
1596
      *lock= 0;
1648
1597
    }
1649
1598
 
1650
 
    if (not create_info->table_existed)
1651
 
      session->drop_open_table(table, identifier);
 
1599
    if (!create_info->table_existed)
 
1600
      session->drop_open_table(table, create_table->db, create_table->table_name);
1652
1601
    return NULL;
1653
1602
  }
1654
1603
 
1659
1608
int
1660
1609
select_create::prepare(List<Item> &values, Select_Lex_Unit *u)
1661
1610
{
1662
 
  DrizzleLock *extra_lock= NULL;
 
1611
  bool lex_identified_temp_table= (table_proto->type() == drizzled::message::Table::TEMPORARY);
 
1612
 
 
1613
  DRIZZLE_LOCK *extra_lock= NULL;
1663
1614
  /*
1664
 
    For replication, the CREATE-SELECT statement is written
1665
 
    in two pieces: the first transaction messsage contains 
1666
 
    the CREATE TABLE statement as a CreateTableStatement message
1667
 
    necessary to create the table.
1668
 
    
1669
 
    The second transaction message contains all the InsertStatement
1670
 
    and associated InsertRecords that should go into the table.
 
1615
    For row-based replication, the CREATE-SELECT statement is written
 
1616
    in two pieces: the first one contain the CREATE TABLE statement
 
1617
    necessary to create the table and the second part contain the rows
 
1618
    that should go into the table.
 
1619
 
 
1620
    For non-temporary tables, the start of the CREATE-SELECT
 
1621
    implicitly commits the previous transaction, and all events
 
1622
    forming the statement will be stored the transaction cache. At end
 
1623
    of the statement, the entire statement is committed as a
 
1624
    transaction, and all events are written to the binary log.
 
1625
 
 
1626
    On the master, the table is locked for the duration of the
 
1627
    statement, but since the CREATE part is replicated as a simple
 
1628
    statement, there is no way to lock the table for accesses on the
 
1629
    slave.  Hence, we have to hold on to the CREATE part of the
 
1630
    statement until the statement has finished.
1671
1631
   */
1672
1632
 
1673
1633
  unit= u;
1674
1634
 
1675
 
  if (not (table= create_table_from_items(session, create_info, create_table,
1676
 
                                          table_proto,
1677
 
                                          alter_info, &values,
1678
 
                                          is_if_not_exists,
1679
 
                                          &extra_lock, identifier)))
1680
 
  {
 
1635
  /*
 
1636
    Start a statement transaction before the create if we are using
 
1637
    row-based replication for the statement.  If we are creating a
 
1638
    temporary table, we need to start a statement transaction.
 
1639
  */
 
1640
 
 
1641
  if (!(table= create_table_from_items(session, create_info, create_table,
 
1642
                                       table_proto,
 
1643
                                       alter_info, &values,
 
1644
                                       is_if_not_exists,
 
1645
                                       &extra_lock)))
1681
1646
    return(-1);                         // abort() deletes table
1682
 
  }
1683
1647
 
1684
1648
  if (extra_lock)
1685
1649
  {
1686
1650
    assert(m_plock == NULL);
1687
1651
 
1688
 
    if (identifier.isTmp())
 
1652
    if (lex_identified_temp_table)
1689
1653
      m_plock= &m_lock;
1690
1654
    else
1691
1655
      m_plock= &session->extra_lock;
1693
1657
    *m_plock= extra_lock;
1694
1658
  }
1695
1659
 
1696
 
  if (table->getShare()->sizeFields() < values.elements)
 
1660
  if (table->s->fields < values.elements)
1697
1661
  {
1698
1662
    my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
1699
1663
    return(-1);
1700
1664
  }
1701
1665
 
1702
1666
 /* First field to copy */
1703
 
  field= table->getFields() + table->getShare()->sizeFields() - values.elements;
 
1667
  field= table->field+table->s->fields - values.elements;
1704
1668
 
1705
1669
  /* Mark all fields that are given values */
1706
1670
  for (Field **f= field ; *f ; f++)
1707
 
  {
1708
 
    table->setWriteSet((*f)->position());
1709
 
  }
 
1671
    table->setWriteSet((*f)->field_index);
1710
1672
 
1711
1673
  /* Don't set timestamp if used */
1712
1674
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1737
1699
 
1738
1700
void select_create::send_error(uint32_t errcode,const char *err)
1739
1701
{
 
1702
 
 
1703
 
1740
1704
  /*
1741
1705
    This will execute any rollbacks that are necessary before writing
1742
1706
    the transcation cache.
1766
1730
      tables.  This can fail, but we should unlock the table
1767
1731
      nevertheless.
1768
1732
    */
1769
 
    if (!table->getShare()->getType())
 
1733
    if (!table->s->tmp_table)
1770
1734
    {
1771
 
      TransactionServices &transaction_services= TransactionServices::singleton();
1772
 
      transaction_services.autocommitOrRollback(session, 0);
 
1735
      ha_autocommit_or_rollback(session, 0);
1773
1736
      (void) session->endActiveTransaction();
1774
1737
    }
1775
1738
 
1777
1740
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1778
1741
    if (m_plock)
1779
1742
    {
1780
 
      session->unlockTables(*m_plock);
 
1743
      mysql_unlock_tables(session, *m_plock);
1781
1744
      *m_plock= NULL;
1782
1745
      m_plock= NULL;
1783
1746
    }
1788
1751
 
1789
1752
void select_create::abort()
1790
1753
{
 
1754
 
 
1755
 
1791
1756
  /*
1792
1757
    In select_insert::abort() we roll back the statement, including
1793
1758
    truncating the transaction cache of the binary log. To do this, we
1804
1769
    log state.
1805
1770
  */
1806
1771
  select_insert::abort();
 
1772
  session->transaction.stmt.modified_non_trans_table= false;
 
1773
 
1807
1774
 
1808
1775
  if (m_plock)
1809
1776
  {
1810
 
    session->unlockTables(*m_plock);
 
1777
    mysql_unlock_tables(session, *m_plock);
1811
1778
    *m_plock= NULL;
1812
1779
    m_plock= NULL;
1813
1780
  }
1816
1783
  {
1817
1784
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1818
1785
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1819
 
    if (not create_info->table_existed)
1820
 
      session->drop_open_table(table, identifier);
 
1786
    if (!create_info->table_existed)
 
1787
      session->drop_open_table(table, create_table->db, create_table->table_name);
1821
1788
    table= NULL;                                    // Safety
1822
1789
  }
1823
1790
}
1824
1791
 
1825
 
} /* namespace drizzled */