~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/alter_table.cc

  • Committer: Brian Aker
  • Date: 2010-03-31 19:14:14 UTC
  • Revision ID: brian@gaz-20100331191414-9yv44mmpvf0tb7l1
Updated to use show schemas specific table.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
 
45
45
#include "drizzled/transaction_services.h"
46
46
 
47
 
#include "drizzled/filesort.h"
48
 
 
49
 
#include "drizzled/message.h"
50
 
 
51
47
using namespace std;
52
48
 
53
49
namespace drizzled
55
51
 
56
52
extern pid_t current_pid;
57
53
 
58
 
static int copy_data_between_tables(Session *session,
59
 
                                    Table *from,Table *to,
 
54
static int copy_data_between_tables(Table *from,Table *to,
60
55
                                    List<CreateField> &create,
61
56
                                    bool ignore,
62
57
                                    uint32_t order_num,
63
 
                                    Order *order,
 
58
                                    order_st *order,
64
59
                                    ha_rows *copied,
65
60
                                    ha_rows *deleted,
66
61
                                    enum enum_enable_or_disable keys_onoff,
69
64
static bool mysql_prepare_alter_table(Session *session,
70
65
                                      Table *table,
71
66
                                      HA_CREATE_INFO *create_info,
72
 
                                      const message::Table &original_proto,
73
67
                                      message::Table &table_message,
74
68
                                      AlterInfo *alter_info);
75
69
 
97
91
    if (create_info.db_type == NULL)
98
92
    {
99
93
      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), 
100
 
               create_table_message.engine().name().c_str());
 
94
               create_table_message.name().c_str());
101
95
 
102
96
      return true;
103
97
    }
104
98
  }
105
99
 
 
100
 
106
101
  /* Must be set in the parser */
107
102
  assert(select_lex->db);
108
103
 
109
104
  /* Chicken/Egg... we need to search for the table, to know if the table exists, so we can build a full identifier from it */
110
 
  message::table::shared_ptr original_table_message;
 
105
  message::Table original_table_message;
111
106
  {
112
 
    TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
 
107
    TableIdentifier identifier(first_table->db, first_table->table_name);
113
108
    if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
114
109
    {
115
 
      std::string path;
116
 
      identifier.getSQLPath(path);
117
 
      my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
 
110
      my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
118
111
      return true;
119
112
    }
120
 
 
121
 
    if (not  create_info.db_type)
122
 
    {
123
 
      create_info.db_type= 
124
 
        plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
125
 
 
126
 
      if (not create_info.db_type)
127
 
      {
128
 
        std::string path;
129
 
        identifier.getSQLPath(path);
130
 
        my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
131
 
        return true;
132
 
      }
133
 
    }
134
113
  }
135
114
 
136
 
  if (not validateCreateTableOption())
137
 
    return true;
138
 
 
139
115
  /* ALTER TABLE ends previous transaction */
140
116
  if (not session->endActiveTransaction())
 
117
  {
141
118
    return true;
 
119
  }
142
120
 
143
 
  if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
 
121
  if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
 
122
  {
144
123
    return true;
 
124
  }
145
125
 
146
126
  bool res;
147
 
  if (original_table_message->type() == message::Table::STANDARD )
 
127
  if (original_table_message.type() == message::Table::STANDARD )
148
128
  {
149
 
    TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
150
 
    TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
151
 
                                   session->lex->name.str ? session->lex->name.str : first_table->getTableName());
 
129
    TableIdentifier identifier(first_table->db, first_table->table_name);
 
130
    TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
 
131
                                   session->lex->name.str ? session->lex->name.str : first_table->table_name);
152
132
 
153
133
    res= alter_table(session, 
154
134
                     identifier,
155
135
                     new_identifier,
156
136
                     &create_info,
157
 
                     *original_table_message,
158
137
                     create_table_message,
159
138
                     first_table,
160
139
                     &alter_info,
161
140
                     select_lex->order_list.elements,
162
 
                     (Order *) select_lex->order_list.first,
 
141
                     (order_st *) select_lex->order_list.first,
163
142
                     session->lex->ignore);
164
143
  }
165
144
  else
166
145
  {
167
 
    TableIdentifier catch22(first_table->getSchemaName(), first_table->getTableName());
168
 
    Table *table= session->find_temporary_table(catch22);
 
146
    Table *table= session->find_temporary_table(first_table);
169
147
    assert(table);
170
148
    {
171
 
      TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
172
 
      TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
173
 
                                     session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
174
 
                                     table->getMutableShare()->getPath());
 
149
      TableIdentifier identifier(first_table->db, first_table->table_name, table->s->path.str);
 
150
      TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
 
151
                                     session->lex->name.str ? session->lex->name.str : first_table->table_name,
 
152
                                     table->s->path.str);
175
153
 
176
154
      res= alter_table(session, 
177
155
                       identifier,
178
156
                       new_identifier,
179
157
                       &create_info,
180
 
                       *original_table_message,
181
158
                       create_table_message,
182
159
                       first_table,
183
160
                       &alter_info,
184
161
                       select_lex->order_list.elements,
185
 
                       (Order *) select_lex->order_list.first,
 
162
                       (order_st *) select_lex->order_list.first,
186
163
                       session->lex->ignore);
187
164
    }
188
165
  }
191
168
     Release the protection against the global read lock and wake
192
169
     everyone, who might want to set a global read lock.
193
170
   */
194
 
  session->startWaitingGlobalReadLock();
195
 
 
 
171
  start_waiting_global_read_lock(session);
196
172
  return res;
197
173
}
198
174
 
240
216
static bool mysql_prepare_alter_table(Session *session,
241
217
                                      Table *table,
242
218
                                      HA_CREATE_INFO *create_info,
243
 
                                      const message::Table &original_proto,
244
219
                                      message::Table &table_message,
245
220
                                      AlterInfo *alter_info)
246
221
{
256
231
  List_iterator<CreateField> field_it(new_create_list);
257
232
  List<Key_part_spec> key_parts;
258
233
  uint32_t used_fields= create_info->used_fields;
259
 
  KeyInfo *key_info= table->key_info;
 
234
  KEY *key_info= table->key_info;
260
235
  bool rc= true;
261
236
 
262
237
  /* Let new create options override the old ones */
263
238
  message::Table::TableOptions *table_options;
264
239
  table_options= table_message.mutable_options();
265
240
 
 
241
  if (! (used_fields & HA_CREATE_USED_BLOCK_SIZE))
 
242
    table_options->set_block_size(table->s->block_size);
266
243
  if (! (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
267
 
    create_info->default_table_charset= table->getShare()->table_charset;
 
244
    create_info->default_table_charset= table->s->table_charset;
268
245
  if (! (used_fields & HA_CREATE_USED_AUTO) &&
269
246
      table->found_next_number_field)
270
247
  {
271
248
    /* Table has an autoincrement, copy value to new table */
272
249
    table->cursor->info(HA_STATUS_AUTO);
273
250
    create_info->auto_increment_value= table->cursor->stats.auto_increment_value;
274
 
    if (create_info->auto_increment_value != original_proto.options().auto_increment_value())
275
 
      table_options->set_has_user_set_auto_increment_value(false);
276
251
  }
 
252
  if (! (used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)
 
253
      && table->s->hasKeyBlockSize())
 
254
    table_options->set_key_block_size(table->s->getKeyBlockSize());
 
255
 
 
256
  if ((used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)
 
257
      && table_options->key_block_size() == 0)
 
258
    table_options->clear_key_block_size();
 
259
 
277
260
  table->restoreRecordAsDefault(); /* Empty record for DEFAULT */
278
261
  CreateField *def;
279
262
 
280
263
  /* First collect all fields from table which isn't in drop_list */
281
264
  Field **f_ptr;
282
265
  Field *field;
283
 
  for (f_ptr= table->getFields(); (field= *f_ptr); f_ptr++)
 
266
  for (f_ptr= table->field; (field= *f_ptr); f_ptr++)
284
267
  {
285
268
    /* Check if field should be dropped */
286
269
    AlterDrop *drop;
347
330
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
348
331
        {
349
332
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
350
 
          return true;
 
333
                goto err;
351
334
        }
352
335
        if ((def->def= alter->def))
353
336
        {
355
338
          def->flags&= ~NO_DEFAULT_VALUE_FLAG;
356
339
        }
357
340
        else
358
 
        {
359
341
          def->flags|= NO_DEFAULT_VALUE_FLAG;
360
 
        }
361
342
        alter_it.remove();
362
343
      }
363
344
    }
367
348
  {
368
349
    if (def->change && ! def->field)
369
350
    {
370
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
371
 
      return true;
 
351
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
 
352
      goto err;
372
353
    }
373
354
    /*
374
 
      If we have been given a field which has no default value, and is not null then we need to bail.
 
355
      Check that the DATE/DATETIME not null field we are going to add is
 
356
      either has a default value or the '0000-00-00' is allowed by the
 
357
      set sql mode.
 
358
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
 
359
      flag to allow ALTER Table only if the table to be altered is empty.
375
360
    */
376
 
    if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->change)
 
361
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
 
362
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
 
363
        ! alter_info->datetime_field &&
 
364
        ! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
 
365
        session->variables.sql_mode & MODE_NO_ZERO_DATE)
377
366
    {
 
367
      alter_info->datetime_field= def;
378
368
      alter_info->error_if_not_empty= true;
379
369
    }
380
370
    if (! def->after)
381
 
    {
382
371
      new_create_list.push_back(def);
383
 
    }
384
372
    else if (def->after == first_keyword)
385
 
    {
386
373
      new_create_list.push_front(def);
387
 
    }
388
374
    else
389
375
    {
390
376
      CreateField *find;
396
382
      }
397
383
      if (! find)
398
384
      {
399
 
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
400
 
        return true;
 
385
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
 
386
        goto err;
401
387
      }
402
388
      find_it.after(def); /* Put element after this */
403
389
      /*
412
398
      */
413
399
      if (alter_info->build_method == HA_BUILD_ONLINE)
414
400
      {
415
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->getQueryString()->c_str());
416
 
        return true;
 
401
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query.c_str());
 
402
        goto err;
417
403
      }
418
404
      alter_info->build_method= HA_BUILD_OFFLINE;
419
405
    }
423
409
    my_error(ER_BAD_FIELD_ERROR,
424
410
             MYF(0),
425
411
             alter_info->alter_list.head()->name,
426
 
             table->getMutableShare()->getTableName());
427
 
    return true;
 
412
             table->s->table_name.str);
 
413
    goto err;
428
414
  }
429
415
  if (! new_create_list.elements)
430
416
  {
431
417
    my_message(ER_CANT_REMOVE_ALL_FIELDS,
432
418
               ER(ER_CANT_REMOVE_ALL_FIELDS),
433
419
               MYF(0));
434
 
    return true;
 
420
    goto err;
435
421
  }
436
422
 
437
423
  /*
438
424
    Collect all keys which isn't in drop list. Add only those
439
425
    for which some fields exists.
440
426
  */
441
 
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++, key_info++)
 
427
  for (uint32_t i= 0; i < table->s->keys; i++, key_info++)
442
428
  {
443
429
    char *key_name= key_info->name;
444
430
    AlterDrop *drop;
455
441
      continue;
456
442
    }
457
443
 
458
 
    KeyPartInfo *key_part= key_info->key_part;
 
444
    KEY_PART_INFO *key_part= key_info->key_part;
459
445
    key_parts.empty();
460
446
    for (uint32_t j= 0; j < key_info->key_parts; j++, key_part++)
461
447
    {
537
523
      new_key_list.push_back(key);
538
524
    }
539
525
  }
540
 
 
541
 
  /* Copy over existing foreign keys */
542
 
  for (int j= 0; j < original_proto.fk_constraint_size(); j++)
543
 
  {
544
 
    AlterDrop *drop;
545
 
    drop_it.rewind();
546
 
    while ((drop= drop_it++))
547
 
    {
548
 
      if (drop->type == AlterDrop::FOREIGN_KEY &&
549
 
          ! my_strcasecmp(system_charset_info, original_proto.fk_constraint(j).name().c_str(), drop->name))
550
 
      {
551
 
        break;
552
 
      }
553
 
    }
554
 
    if (drop)
555
 
    {
556
 
      drop_it.remove();
557
 
      continue;
558
 
    }
559
 
 
560
 
    message::Table::ForeignKeyConstraint *pfkey= table_message.add_fk_constraint();
561
 
    *pfkey= original_proto.fk_constraint(j);
562
 
  }
563
 
 
564
526
  {
565
527
    Key *key;
566
528
    while ((key= key_it++)) /* Add new keys */
567
529
    {
568
 
      if (key->type == Key::FOREIGN_KEY)
569
 
      {
570
 
        if (((Foreign_key *)key)->validate(new_create_list))
571
 
        {
572
 
          return true;
573
 
        }
574
 
 
575
 
        Foreign_key *fkey= (Foreign_key*)key;
576
 
        add_foreign_key_to_table_message(&table_message,
577
 
                                         fkey->name.str,
578
 
                                         fkey->columns,
579
 
                                         fkey->ref_table,
580
 
                                         fkey->ref_columns,
581
 
                                         fkey->delete_opt,
582
 
                                         fkey->update_opt,
583
 
                                         fkey->match_opt);
584
 
      }
585
 
 
 
530
      if (key->type == Key::FOREIGN_KEY &&
 
531
          ((Foreign_key *)key)->validate(new_create_list))
 
532
        goto err;
586
533
      if (key->type != Key::FOREIGN_KEY)
587
534
        new_key_list.push_back(key);
588
 
 
589
535
      if (key->name.str && is_primary_key_name(key->name.str))
590
536
      {
591
537
        my_error(ER_WRONG_NAME_FOR_INDEX,
592
538
                 MYF(0),
593
539
                 key->name.str);
594
 
        return true;
 
540
        goto err;
595
541
      }
596
542
    }
597
543
  }
598
544
 
599
 
  /* Fix names of foreign keys being added */
600
 
  for (int j= 0; j < table_message.fk_constraint_size(); j++)
601
 
  {
602
 
    if (! table_message.fk_constraint(j).has_name())
603
 
    {
604
 
      std::string name(table->getMutableShare()->getTableName());
605
 
      char number[20];
606
 
 
607
 
      name.append("_ibfk_");
608
 
      snprintf(number, sizeof(number), "%d", j+1);
609
 
      name.append(number);
610
 
 
611
 
      message::Table::ForeignKeyConstraint *pfkey= table_message.mutable_fk_constraint(j);
612
 
      pfkey->set_name(name);
613
 
    }
614
 
  }
615
 
 
616
545
  if (alter_info->drop_list.elements)
617
546
  {
618
547
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
619
548
             MYF(0),
620
549
             alter_info->drop_list.head()->name);
621
 
    return true;
 
550
    goto err;
622
551
  }
623
552
  if (alter_info->alter_list.elements)
624
553
  {
625
554
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
626
555
             MYF(0),
627
556
             alter_info->alter_list.head()->name);
628
 
    return true;
 
557
    goto err;
629
558
  }
630
559
 
631
560
  if (not table_message.options().has_comment()
632
 
      && table->getMutableShare()->hasComment())
633
 
    table_options->set_comment(table->getMutableShare()->getComment());
 
561
      && table->s->hasComment())
 
562
    table_options->set_comment(table->s->getComment());
634
563
 
635
 
  if (table->getShare()->getType())
 
564
  if (table->s->tmp_table)
636
565
  {
637
566
    table_message.set_type(message::Table::TEMPORARY);
638
567
  }
639
568
 
640
569
  table_message.set_creation_timestamp(table->getShare()->getTableProto()->creation_timestamp());
641
 
  table_message.set_version(table->getShare()->getTableProto()->version());
642
 
  table_message.set_uuid(table->getShare()->getTableProto()->uuid());
 
570
 
 
571
  table_message.set_update_timestamp(time(NULL));
 
572
 
 
573
  if (not table_message.options().has_comment()
 
574
      && table->s->hasComment())
 
575
    table_options->set_comment(table->s->getComment());
643
576
 
644
577
  rc= false;
645
578
  alter_info->create_list.swap(new_create_list);
646
579
  alter_info->key_list.swap(new_key_list);
647
 
 
648
 
  size_t num_engine_options= table_message.engine().options_size();
649
 
  size_t original_num_engine_options= original_proto.engine().options_size();
650
 
  for (size_t x= 0; x < original_num_engine_options; ++x)
651
 
  {
652
 
    bool found= false;
653
 
 
654
 
    for (size_t y= 0; y < num_engine_options; ++y)
655
 
    {
656
 
      found= not table_message.engine().options(y).name().compare(original_proto.engine().options(x).name());
657
 
      
658
 
      if (found)
659
 
        break;
660
 
    }
661
 
 
662
 
    if (not found)
663
 
    {
664
 
      message::Engine::Option *opt= table_message.mutable_engine()->add_options();
665
 
 
666
 
      opt->set_name(original_proto.engine().options(x).name());
667
 
      opt->set_state(original_proto.engine().options(x).state());
668
 
    }
669
 
  }
670
 
 
671
 
  drizzled::message::update(table_message);
672
 
 
673
 
  return false;
 
580
err:
 
581
  return rc;
674
582
}
675
583
 
676
584
/* table_list should contain just one table */
711
619
    goto err;
712
620
 
713
621
  /* The ALTER Table is always in its own transaction */
714
 
  error= transaction_services.autocommitOrRollback(session, false);
715
 
  if (not session->endActiveTransaction())
 
622
  error= transaction_services.ha_autocommit_or_rollback(session, false);
 
623
  if (! session->endActiveTransaction())
716
624
    error=1;
717
 
 
718
625
  if (error)
719
626
    goto err;
720
 
 
721
 
  write_bin_log(session, *session->getQueryString());
 
627
  write_bin_log(session, session->query.c_str());
722
628
 
723
629
err:
724
 
  (void) transaction_services.autocommitOrRollback(session, error);
 
630
  (void) transaction_services.ha_autocommit_or_rollback(session, error);
725
631
  session->tablespace_op=false;
726
632
 
727
633
  if (error == 0)
749
655
    false  OK
750
656
    true   Error
751
657
*/
752
 
static bool alter_table_manage_keys(Session *session,
753
 
                                    Table *table, int indexes_were_disabled,
754
 
                                    enum enum_enable_or_disable keys_onoff)
 
658
static bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
 
659
                             enum enum_enable_or_disable keys_onoff)
755
660
{
756
661
  int error= 0;
757
662
  switch (keys_onoff) {
759
664
    error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
760
665
    break;
761
666
  case LEAVE_AS_IS:
762
 
    if (not indexes_were_disabled)
 
667
    if (!indexes_were_disabled)
763
668
      break;
764
669
    /* fall-through: disabled indexes */
765
670
  case DISABLE:
768
673
 
769
674
  if (error == HA_ERR_WRONG_COMMAND)
770
675
  {
771
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
676
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
772
677
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
773
 
                        table->getMutableShare()->getTableName());
 
678
                        table->s->table_name.str);
774
679
    error= 0;
775
680
  } else if (error)
776
681
    table->print_error(error, MYF(0));
791
696
 
792
697
      if (session.find_temporary_table(new_table_identifier))
793
698
      {
794
 
        std::string path;
795
 
        new_table_identifier.getSQLPath(path);
796
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
699
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
797
700
        return false;
798
701
      }
799
702
    }
806
709
 
807
710
      if (not name_lock)
808
711
      {
809
 
        std::string path;
810
 
        new_table_identifier.getSQLPath(path);
811
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
712
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
812
713
        return false;
813
714
      }
814
715
 
815
716
      if (plugin::StorageEngine::doesTableExist(session, new_table_identifier))
816
717
      {
817
 
        std::string path;
818
 
        new_table_identifier.getSQLPath(path);
819
 
 
820
718
        /* Table will be closed by Session::executeCommand() */
821
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
719
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
822
720
 
823
 
        table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
 
721
        pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
824
722
        session.unlink_open_table(name_lock);
825
 
        table::Cache::singleton().mutex().unlock();
 
723
        pthread_mutex_unlock(&LOCK_open);
826
724
 
827
725
        return false;
828
726
      }
879
777
                                 TableIdentifier &original_table_identifier,
880
778
                                 TableIdentifier &new_table_identifier,
881
779
                                 HA_CREATE_INFO *create_info,
882
 
                                 const message::Table &original_proto,
883
780
                                 message::Table &create_proto,
884
781
                                 TableList *table_list,
885
782
                                 AlterInfo *alter_info,
886
783
                                 uint32_t order_num,
887
 
                                 Order *order,
 
784
                                 order_st *order,
888
785
                                 bool ignore)
889
786
{
 
787
  Table *new_table= NULL;
890
788
  int error= 0;
891
789
  char tmp_name[80];
892
790
  char old_name[32];
893
791
  ha_rows copied= 0;
894
792
  ha_rows deleted= 0;
895
793
 
896
 
  if (not original_table_identifier.isValid())
897
 
    return true;
898
 
 
899
 
  if (not new_table_identifier.isValid())
900
 
    return true;
 
794
  message::Table *original_table_definition= table->s->getTableProto();
901
795
 
902
796
  session->set_proc_info("init");
903
797
 
906
800
  plugin::StorageEngine *new_engine;
907
801
  plugin::StorageEngine *original_engine;
908
802
 
909
 
  original_engine= table->getMutableShare()->getEngine();
 
803
  original_engine= table->s->getEngine();
910
804
 
911
805
  if (not create_info->db_type)
912
806
  {
934
828
  if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
935
829
      new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
936
830
  {
937
 
    std::string path;
938
 
    new_table_identifier.getSQLPath(path);
939
 
    my_error(ER_ILLEGAL_HA, MYF(0), path.c_str());
 
831
    my_error(ER_ILLEGAL_HA, MYF(0), new_table_identifier.getSQLPath().c_str());
940
832
 
941
833
    return true;
942
834
  }
943
835
 
 
836
  if (create_info->row_type == ROW_TYPE_NOT_USED)
 
837
  {
 
838
    message::Table::TableOptions *table_options;
 
839
    table_options= create_proto.mutable_options();
 
840
 
 
841
    create_info->row_type= table->s->row_type;
 
842
    table_options->set_row_type(original_table_definition->options().row_type());
 
843
  }
 
844
 
944
845
  session->set_proc_info("setup");
945
846
 
946
847
  /*
954
855
    tmp.reset(ALTER_KEYS_ONOFF);
955
856
    tmp&= alter_info->flags;
956
857
 
957
 
    if (! (tmp.any()) && ! table->getShare()->getType()) // no need to touch frm
 
858
    if (! (tmp.any()) && ! table->s->tmp_table) // no need to touch frm
958
859
    {
959
860
      switch (alter_info->keys_onoff)
960
861
      {
970
871
          while the fact that the table is still open gives us protection
971
872
          from concurrent DDL statements.
972
873
        */
973
 
        table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
 
874
        pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
974
875
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
975
 
        table::Cache::singleton().mutex().unlock();
 
876
        pthread_mutex_unlock(&LOCK_open);
976
877
        error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
977
878
        /* COND_refresh will be signaled in close_thread_tables() */
978
879
        break;
979
880
      case DISABLE:
980
 
        table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
 
881
        pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
981
882
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
982
 
        table::Cache::singleton().mutex().unlock();
 
883
        pthread_mutex_unlock(&LOCK_open);
983
884
        error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
984
885
        /* COND_refresh will be signaled in close_thread_tables() */
985
886
        break;
994
895
        error= 0;
995
896
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
996
897
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
997
 
                            table->getAlias());
 
898
                            table->alias);
998
899
      }
999
900
 
1000
 
      table::Cache::singleton().mutex().lock(); /* Lock to remove all instances of table from table cache before ALTER */
 
901
      pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
1001
902
      /*
1002
903
        Unlike to the above case close_cached_table() below will remove ALL
1003
904
        instances of Table from table cache (it will also remove table lock
1004
905
        held by this thread). So to make actual table renaming and writing
1005
906
        to binlog atomic we have to put them into the same critical section
1006
 
        protected by table::Cache::singleton().mutex() mutex. This also removes gap for races between
 
907
        protected by LOCK_open mutex. This also removes gap for races between
1007
908
        access() and mysql_rename_table() calls.
1008
909
      */
1009
910
 
1025
926
        */
1026
927
        if (plugin::StorageEngine::doesTableExist(*session, new_table_identifier))
1027
928
        {
1028
 
          std::string path;
1029
 
          new_table_identifier.getSQLPath(path);
1030
 
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
929
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
1031
930
          error= -1;
1032
931
        }
1033
932
        else
1034
933
        {
1035
 
          if (mysql_rename_table(*session, original_engine, original_table_identifier, new_table_identifier))
 
934
          if (mysql_rename_table(original_engine, original_table_identifier, new_table_identifier, 0))
1036
935
          {
1037
936
            error= -1;
1038
937
          }
1044
943
        error= 0;
1045
944
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1046
945
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1047
 
                            table->getAlias());
 
946
                            table->alias);
1048
947
      }
1049
948
 
1050
949
      if (error == 0)
1051
950
      {
1052
 
        TransactionServices &transaction_services= TransactionServices::singleton();
1053
 
        transaction_services.allocateNewTransactionId();
1054
 
        write_bin_log(session, *session->getQueryString());
 
951
        write_bin_log(session, session->query.c_str());
1055
952
        session->my_ok();
1056
953
      }
1057
954
      else if (error > 0)
1060
957
        error= -1;
1061
958
      }
1062
959
 
1063
 
      table::Cache::singleton().mutex().unlock();
 
960
      pthread_mutex_unlock(&LOCK_open);
1064
961
      table_list->table= NULL;
1065
962
 
1066
963
      return error;
1070
967
  /* We have to do full alter table. */
1071
968
  new_engine= create_info->db_type;
1072
969
 
1073
 
  if (mysql_prepare_alter_table(session, table, create_info, original_proto, create_proto, alter_info))
 
970
  if (mysql_prepare_alter_table(session, table, create_info, create_proto, alter_info))
1074
971
  {
1075
972
    return true;
1076
973
  }
1100
997
  }
1101
998
 
1102
999
  /* Open the table so we need to copy the data to it. */
1103
 
  Table *new_table= open_alter_table(session, table, new_table_as_temporary);
1104
 
 
 
1000
  new_table= open_alter_table(session, table, new_table_as_temporary);
1105
1001
 
1106
1002
  if (not new_table)
1107
1003
  {
1108
 
    plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1004
    quick_rm_table(*session, new_table_as_temporary);
1109
1005
    return true;
1110
1006
  }
1111
1007
 
1112
1008
  /* Copy the data if necessary. */
1113
1009
  {
1114
 
    /* We must not ignore bad input! */
1115
 
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;    // calc cuted fields
 
1010
    session->count_cuted_fields= CHECK_FIELD_WARN;      // calc cuted fields
1116
1011
    session->cuted_fields= 0L;
1117
1012
    session->set_proc_info("copy to tmp table");
1118
1013
    copied= deleted= 0;
1120
1015
    /* We don't want update TIMESTAMP fields during ALTER Table. */
1121
1016
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1122
1017
    new_table->next_number_field= new_table->found_next_number_field;
1123
 
    error= copy_data_between_tables(session,
1124
 
                                    table,
 
1018
    error= copy_data_between_tables(table,
1125
1019
                                    new_table,
1126
1020
                                    alter_info->create_list,
1127
1021
                                    ignore,
1133
1027
                                    alter_info->error_if_not_empty);
1134
1028
 
1135
1029
    /* We must not ignore bad input! */
1136
 
    assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
 
1030
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1137
1031
  }
1138
1032
 
1139
1033
  /* Now we need to resolve what just happened with the data copy. */
1149
1043
    */
1150
1044
    if (alter_info->error_if_not_empty && session->row_count)
1151
1045
    {
1152
 
      my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
 
1046
      const char *f_val= 0;
 
1047
      enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
 
1048
 
 
1049
      switch (alter_info->datetime_field->sql_type)
 
1050
      {
 
1051
      case DRIZZLE_TYPE_DATE:
 
1052
        f_val= "0000-00-00";
 
1053
        t_type= DRIZZLE_TIMESTAMP_DATE;
 
1054
        break;
 
1055
      case DRIZZLE_TYPE_DATETIME:
 
1056
        f_val= "0000-00-00 00:00:00";
 
1057
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
 
1058
        break;
 
1059
      default:
 
1060
        /* Shouldn't get here. */
 
1061
        assert(0);
 
1062
      }
 
1063
      bool save_abort_on_warning= session->abort_on_warning;
 
1064
      session->abort_on_warning= true;
 
1065
      make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
1066
                                   f_val, internal::strlength(f_val), t_type,
 
1067
                                   alter_info->datetime_field->field_name);
 
1068
      session->abort_on_warning= save_abort_on_warning;
1153
1069
    }
1154
1070
 
1155
1071
    if (original_table_identifier.isTmp())
1161
1077
      }
1162
1078
      else
1163
1079
      {
1164
 
        plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1080
        quick_rm_table(*session, new_table_as_temporary);
1165
1081
      }
1166
1082
 
1167
1083
      return true;
1175
1091
          Note that MERGE tables do not have their children attached here.
1176
1092
        */
1177
1093
        new_table->intern_close_table();
1178
 
        if (new_table->hasShare())
1179
 
        {
1180
 
          delete new_table->getMutableShare();
1181
 
        }
1182
 
 
1183
 
        delete new_table;
 
1094
        free(new_table);
1184
1095
      }
1185
1096
 
1186
 
      table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
 
1097
      pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1187
1098
 
1188
 
      plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1189
 
      table::Cache::singleton().mutex().unlock();
 
1099
      quick_rm_table(*session, new_table_as_temporary);
 
1100
      pthread_mutex_unlock(&LOCK_open);
1190
1101
 
1191
1102
      return true;
1192
1103
    }
1197
1108
    /* Close lock if this is a transactional table */
1198
1109
    if (session->lock)
1199
1110
    {
1200
 
      session->unlockTables(session->lock);
 
1111
      mysql_unlock_tables(session, session->lock);
1201
1112
      session->lock= 0;
1202
1113
    }
1203
1114
 
1205
1116
    session->close_temporary_table(table);
1206
1117
 
1207
1118
    /* Should pass the 'new_name' as we store table name in the cache */
1208
 
    new_table->getMutableShare()->setIdentifier(new_table_identifier);
 
1119
    if (new_table->renameAlterTemporaryTable(new_table_identifier))
 
1120
    {
 
1121
      session->close_temporary_table(new_table);
 
1122
 
 
1123
      return true;
 
1124
    }
1209
1125
 
1210
1126
    new_table_identifier.setPath(new_table_as_temporary.getPath());
1211
1127
 
1212
 
    if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
 
1128
    if (mysql_rename_table(new_engine, new_table_as_temporary, new_table_identifier, FN_FROM_IS_TMP) != 0)
1213
1129
    {
1214
1130
      return true;
1215
1131
    }
1224
1140
        Note that MERGE tables do not have their children attached here.
1225
1141
      */
1226
1142
      new_table->intern_close_table();
1227
 
 
1228
 
      if (new_table->hasShare())
1229
 
      {
1230
 
        delete new_table->getMutableShare();
1231
 
      }
1232
 
 
1233
 
      delete new_table;
 
1143
      free(new_table);
1234
1144
    }
1235
1145
 
1236
 
    table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
 
1146
    pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1237
1147
 
1238
1148
    /*
1239
1149
      Data is copied. Now we:
1272
1182
      compare_table(). Then, we need one additional call to
1273
1183
    */
1274
1184
    TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1275
 
                                           old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1276
 
                                         message::Table::TEMPORARY);
 
1185
                                           old_name, message::Table::TEMPORARY);
1277
1186
 
1278
 
    if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
 
1187
    if (mysql_rename_table(original_engine, original_table_identifier, original_table_to_drop, FN_TO_IS_TMP))
1279
1188
    {
1280
1189
      error= 1;
1281
 
      plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1190
      quick_rm_table(*session, new_table_as_temporary);
1282
1191
    }
1283
1192
    else
1284
1193
    {
1285
 
      if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
 
1194
      if (mysql_rename_table(new_engine, new_table_as_temporary, new_table_identifier, FN_FROM_IS_TMP) != 0)
1286
1195
      {
1287
1196
        /* Try to get everything back. */
1288
1197
        error= 1;
1289
1198
 
1290
 
        plugin::StorageEngine::dropTable(*session, new_table_identifier);
1291
 
 
1292
 
        plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1293
 
 
1294
 
        mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
 
1199
        quick_rm_table(*session, new_table_identifier);
 
1200
 
 
1201
        quick_rm_table(*session, new_table_as_temporary);
 
1202
 
 
1203
        mysql_rename_table(original_engine, original_table_to_drop, original_table_identifier, FN_FROM_IS_TMP);
1295
1204
      }
1296
1205
      else
1297
1206
      {
1298
 
        plugin::StorageEngine::dropTable(*session, original_table_to_drop);
 
1207
        quick_rm_table(*session, original_table_to_drop);
1299
1208
      }
1300
1209
    }
1301
1210
 
1307
1216
        from list of open tables list and table cache.
1308
1217
      */
1309
1218
      session->unlink_open_table(table);
1310
 
      table::Cache::singleton().mutex().unlock();
 
1219
      pthread_mutex_unlock(&LOCK_open);
1311
1220
 
1312
1221
      return true;
1313
1222
    }
1314
1223
 
1315
 
    table::Cache::singleton().mutex().unlock();
 
1224
    pthread_mutex_unlock(&LOCK_open);
1316
1225
 
1317
1226
    session->set_proc_info("end");
1318
1227
 
1319
 
    write_bin_log(session, *session->getQueryString());
 
1228
    write_bin_log(session, session->query.c_str());
1320
1229
    table_list->table= NULL;
1321
1230
  }
1322
1231
 
1344
1253
                 TableIdentifier &original_table_identifier,
1345
1254
                 TableIdentifier &new_table_identifier,
1346
1255
                 HA_CREATE_INFO *create_info,
1347
 
                 const message::Table &original_proto,
1348
1256
                 message::Table &create_proto,
1349
1257
                 TableList *table_list,
1350
1258
                 AlterInfo *alter_info,
1351
1259
                 uint32_t order_num,
1352
 
                 Order *order,
 
1260
                 order_st *order,
1353
1261
                 bool ignore)
1354
1262
{
1355
1263
  bool error;
1385
1293
                                original_table_identifier,
1386
1294
                                new_table_identifier,
1387
1295
                                create_info,
1388
 
                                original_proto,
1389
1296
                                create_proto,
1390
1297
                                table_list,
1391
1298
                                alter_info,
1395
1302
 
1396
1303
    if (name_lock)
1397
1304
    {
1398
 
      table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
 
1305
      pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1399
1306
      session->unlink_open_table(name_lock);
1400
 
      table::Cache::singleton().mutex().unlock();
 
1307
      pthread_mutex_unlock(&LOCK_open);
1401
1308
    }
1402
1309
  }
1403
1310
 
1406
1313
/* alter_table */
1407
1314
 
1408
1315
static int
1409
 
copy_data_between_tables(Session *session,
1410
 
                         Table *from, Table *to,
 
1316
copy_data_between_tables(Table *from, Table *to,
1411
1317
                         List<CreateField> &create,
1412
1318
                         bool ignore,
1413
 
                         uint32_t order_num, Order *order,
 
1319
                         uint32_t order_num, order_st *order,
1414
1320
                         ha_rows *copied,
1415
1321
                         ha_rows *deleted,
1416
1322
                         enum enum_enable_or_disable keys_onoff,
1419
1325
  int error= 0;
1420
1326
  CopyField *copy,*copy_end;
1421
1327
  ulong found_count,delete_count;
 
1328
  Session *session= current_session;
1422
1329
  uint32_t length= 0;
1423
 
  SortField *sortorder;
1424
 
  ReadRecord info;
 
1330
  SORT_FIELD *sortorder;
 
1331
  READ_RECORD info;
1425
1332
  TableList   tables;
1426
1333
  List<Item>   fields;
1427
1334
  List<Item>   all_fields;
1437
1344
  */
1438
1345
  TransactionServices &transaction_services= TransactionServices::singleton();
1439
1346
 
1440
 
  /* 
1441
 
   * LP Bug #552420 
1442
 
   *
1443
 
   * Since open_temporary_table() doesn't invoke lockTables(), we
1444
 
   * don't get the usual automatic call to StorageEngine::startStatement(), so
1445
 
   * we manually call it here...
1446
 
   */
1447
 
  to->getMutableShare()->getEngine()->startStatement(session);
1448
 
 
1449
 
  if (!(copy= new CopyField[to->getShare()->sizeFields()]))
 
1347
  if (!(copy= new CopyField[to->s->fields]))
1450
1348
    return -1;
1451
1349
 
1452
1350
  if (to->cursor->ha_external_lock(session, F_WRLCK))
1453
1351
    return -1;
1454
1352
 
1455
1353
  /* We need external lock before we can disable/enable keys */
1456
 
  alter_table_manage_keys(session, to, from->cursor->indexes_are_disabled(), keys_onoff);
 
1354
  alter_table_manage_keys(to, from->cursor->indexes_are_disabled(), keys_onoff);
1457
1355
 
1458
1356
  /* We can abort alter table for any table type */
1459
1357
  session->abort_on_warning= !ignore;
1464
1362
  List_iterator<CreateField> it(create);
1465
1363
  CreateField *def;
1466
1364
  copy_end=copy;
1467
 
  for (Field **ptr= to->getFields(); *ptr ; ptr++)
 
1365
  for (Field **ptr=to->field ; *ptr ; ptr++)
1468
1366
  {
1469
1367
    def=it++;
1470
1368
    if (def->field)
1481
1379
 
1482
1380
  if (order)
1483
1381
  {
1484
 
    if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
 
1382
    if (to->s->primary_key != MAX_KEY && to->cursor->primary_key_is_clustered())
1485
1383
    {
1486
1384
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
1487
1385
      snprintf(warn_buff, sizeof(warn_buff),
1488
1386
               _("order_st BY ignored because there is a user-defined clustered "
1489
1387
                 "index in the table '%-.192s'"),
1490
 
               from->getMutableShare()->getTableName());
 
1388
               from->s->table_name.str);
1491
1389
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1492
1390
                   warn_buff);
1493
1391
    }
1494
1392
    else
1495
1393
    {
1496
 
      FileSort filesort(*session);
1497
1394
      from->sort.io_cache= new internal::IO_CACHE;
 
1395
      memset(from->sort.io_cache, 0, sizeof(internal::IO_CACHE));
1498
1396
 
1499
1397
      memset(&tables, 0, sizeof(tables));
1500
1398
      tables.table= from;
1501
 
      tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1502
 
      tables.alias= const_cast<char *>(tables.getTableName());
1503
 
      tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
 
1399
      tables.alias= tables.table_name= from->s->table_name.str;
 
1400
      tables.db= const_cast<char *>(from->s->getSchemaName());
1504
1401
      error= 1;
1505
1402
 
1506
1403
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1507
1404
          setup_order(session, session->lex->select_lex.ref_pointer_array,
1508
1405
                      &tables, fields, all_fields, order) ||
1509
1406
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1510
 
          (from->sort.found_records= filesort.run(from, sortorder, length,
1511
 
                                                  (optimizer::SqlSelect *) 0, HA_POS_ERROR,
1512
 
                                                  1, examined_rows)) == HA_POS_ERROR)
 
1407
          (from->sort.found_records= filesort(session, from, sortorder, length,
 
1408
                                              (optimizer::SqlSelect *) 0, HA_POS_ERROR,
 
1409
                                              1, &examined_rows)) ==
 
1410
          HA_POS_ERROR)
1513
1411
      {
1514
1412
        goto err;
1515
1413
      }
1518
1416
 
1519
1417
  /* Tell handler that we have values for all columns in the to table */
1520
1418
  to->use_all_columns();
1521
 
  info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
 
1419
  init_read_record(&info, session, from, (optimizer::SqlSelect *) 0, 1,1);
1522
1420
  if (ignore)
1523
1421
    to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1524
1422
  session->row_count= 0;
1525
1423
  to->restoreRecordAsDefault();        // Create empty record
1526
1424
  while (!(error=info.read_record(&info)))
1527
1425
  {
1528
 
    if (session->getKilled())
 
1426
    if (session->killed)
1529
1427
    {
1530
1428
      session->send_kill_message();
1531
1429
      error= 1;
1546
1444
        to->next_number_field->reset();
1547
1445
    }
1548
1446
 
1549
 
    for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
 
1447
    for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1550
1448
    {
1551
 
      if (not copy->to_field->hasDefault() and copy->from_null_ptr and  *copy->from_null_ptr & copy->from_bit)
1552
 
      {
1553
 
        copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1554
 
                                    ER_WARN_DATA_TRUNCATED, 1);
1555
 
        copy->to_field->reset();
1556
 
        error= 1;
1557
 
        break;
1558
 
      }
1559
 
 
1560
1449
      copy_ptr->do_copy(copy_ptr);
1561
1450
    }
1562
 
 
1563
 
    if (error)
1564
 
    {
1565
 
      break;
1566
 
    }
1567
 
 
1568
1451
    prev_insert_id= to->cursor->next_insert_id;
1569
 
    error= to->cursor->insertRecord(to->record[0]);
 
1452
    error= to->cursor->ha_write_row(to->record[0]);
1570
1453
    to->auto_increment_field_not_null= false;
1571
 
 
1572
1454
    if (error)
1573
1455
    { 
1574
 
      if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
1456
      if (!ignore ||
 
1457
          to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1575
1458
      { 
1576
1459
        to->print_error(error, MYF(0));
1577
1460
        break;
1580
1463
      delete_count++;
1581
1464
    }
1582
1465
    else
1583
 
    {
1584
1466
      found_count++;
1585
 
    }
1586
1467
  }
1587
 
 
1588
 
  info.end_read_record();
 
1468
  end_read_record(&info);
1589
1469
  from->free_io_cache();
1590
1470
  delete [] copy;                               // This is never 0
1591
1471
 
1600
1480
    Ensure that the new table is saved properly to disk so that we
1601
1481
    can do a rename
1602
1482
  */
1603
 
  if (transaction_services.autocommitOrRollback(session, false))
 
1483
  if (transaction_services.ha_autocommit_or_rollback(session, false))
1604
1484
    error=1;
1605
1485
  if (! session->endActiveTransaction())
1606
1486
    error=1;
1613
1493
  to->cursor->ha_release_auto_increment();
1614
1494
  if (to->cursor->ha_external_lock(session,F_UNLCK))
1615
1495
    error=1;
1616
 
 
1617
1496
  return(error > 0 ? -1 : 0);
1618
1497
}
1619
1498
 
1632
1511
  */
1633
1512
  create_proto.set_name(identifier.getTableName());
1634
1513
 
1635
 
  create_proto.mutable_engine()->set_name(create_info->db_type->getName());
 
1514
  message::Table::StorageEngine *protoengine;
 
1515
  protoengine= create_proto.mutable_engine();
 
1516
  protoengine->set_name(create_info->db_type->getName());
1636
1517
 
1637
1518
  error= mysql_create_table(session,
1638
1519
                            identifier,
1646
1527
  Table *new_table;
1647
1528
 
1648
1529
  /* Open the table so we need to copy the data to it. */
1649
 
  if (table->getShare()->getType())
 
1530
  if (table->s->tmp_table)
1650
1531
  {
1651
1532
    TableList tbl;
1652
 
    tbl.setSchemaName(const_cast<char *>(identifier.getSchemaName().c_str()));
 
1533
    tbl.db= const_cast<char *>(identifier.getSchemaName().c_str());
1653
1534
    tbl.alias= const_cast<char *>(identifier.getTableName().c_str());
1654
 
    tbl.setTableName(const_cast<char *>(identifier.getTableName().c_str()));
 
1535
    tbl.table_name= const_cast<char *>(identifier.getTableName().c_str());
1655
1536
 
1656
1537
    /* Table is in session->temporary_tables */
1657
1538
    new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);