~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/alter_table.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 16:12:58 UTC
  • mto: This revision was merged to the branch mainline in revision 1720.
  • Revision ID: brian@tangent.org-20100818161258-1vm71da888dfvwsx
Remove the code surrounding stack trace.

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
 
52
52
extern pid_t current_pid;
53
53
 
54
 
static int copy_data_between_tables(Table *from,Table *to,
 
54
static int copy_data_between_tables(Session *session,
 
55
                                    Table *from,Table *to,
55
56
                                    List<CreateField> &create,
56
57
                                    bool ignore,
57
58
                                    uint32_t order_num,
64
65
static bool mysql_prepare_alter_table(Session *session,
65
66
                                      Table *table,
66
67
                                      HA_CREATE_INFO *create_info,
 
68
                                      const message::Table &original_proto,
67
69
                                      message::Table &table_message,
68
70
                                      AlterInfo *alter_info);
69
71
 
97
99
    }
98
100
  }
99
101
 
100
 
 
101
102
  /* Must be set in the parser */
102
103
  assert(select_lex->db);
103
104
 
110
111
      my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
111
112
      return true;
112
113
    }
 
114
 
 
115
    if (not  create_info.db_type)
 
116
    {
 
117
      create_info.db_type= 
 
118
        plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
 
119
 
 
120
      if (not create_info.db_type)
 
121
      {
 
122
        my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
 
123
        return true;
 
124
      }
 
125
    }
 
126
  }
 
127
 
 
128
  if (not validateCreateTableOption())
 
129
  {
 
130
    return true;
113
131
  }
114
132
 
115
133
  /* ALTER TABLE ends previous transaction */
134
152
                     identifier,
135
153
                     new_identifier,
136
154
                     &create_info,
 
155
                     original_table_message,
137
156
                     create_table_message,
138
157
                     first_table,
139
158
                     &alter_info,
146
165
    Table *table= session->find_temporary_table(first_table);
147
166
    assert(table);
148
167
    {
149
 
      TableIdentifier identifier(first_table->db, first_table->table_name, table->s->path.str);
 
168
      TableIdentifier identifier(first_table->db, first_table->table_name, table->getMutableShare()->getPath());
150
169
      TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
151
170
                                     session->lex->name.str ? session->lex->name.str : first_table->table_name,
152
 
                                     table->s->path.str);
 
171
                                     table->getMutableShare()->getPath());
153
172
 
154
173
      res= alter_table(session, 
155
174
                       identifier,
156
175
                       new_identifier,
157
176
                       &create_info,
 
177
                       original_table_message,
158
178
                       create_table_message,
159
179
                       first_table,
160
180
                       &alter_info,
216
236
static bool mysql_prepare_alter_table(Session *session,
217
237
                                      Table *table,
218
238
                                      HA_CREATE_INFO *create_info,
 
239
                                      const message::Table &original_proto,
219
240
                                      message::Table &table_message,
220
241
                                      AlterInfo *alter_info)
221
242
{
231
252
  List_iterator<CreateField> field_it(new_create_list);
232
253
  List<Key_part_spec> key_parts;
233
254
  uint32_t used_fields= create_info->used_fields;
234
 
  KEY *key_info= table->key_info;
 
255
  KeyInfo *key_info= table->key_info;
235
256
  bool rc= true;
236
257
 
237
258
  /* Let new create options override the old ones */
238
259
  message::Table::TableOptions *table_options;
239
260
  table_options= table_message.mutable_options();
240
261
 
241
 
  if (! (used_fields & HA_CREATE_USED_BLOCK_SIZE))
242
 
    table_options->set_block_size(table->s->block_size);
243
262
  if (! (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
244
 
    create_info->default_table_charset= table->s->table_charset;
 
263
    create_info->default_table_charset= table->getShare()->table_charset;
245
264
  if (! (used_fields & HA_CREATE_USED_AUTO) &&
246
265
      table->found_next_number_field)
247
266
  {
249
268
    table->cursor->info(HA_STATUS_AUTO);
250
269
    create_info->auto_increment_value= table->cursor->stats.auto_increment_value;
251
270
  }
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
 
 
260
271
  table->restoreRecordAsDefault(); /* Empty record for DEFAULT */
261
272
  CreateField *def;
262
273
 
263
274
  /* First collect all fields from table which isn't in drop_list */
264
275
  Field **f_ptr;
265
276
  Field *field;
266
 
  for (f_ptr= table->field; (field= *f_ptr); f_ptr++)
 
277
  for (f_ptr= table->getFields(); (field= *f_ptr); f_ptr++)
267
278
  {
268
279
    /* Check if field should be dropped */
269
280
    AlterDrop *drop;
348
359
  {
349
360
    if (def->change && ! def->field)
350
361
    {
351
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
 
362
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
352
363
      goto err;
353
364
    }
354
365
    /*
361
372
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
362
373
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
363
374
        ! alter_info->datetime_field &&
364
 
        ! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
365
 
        session->variables.sql_mode & MODE_NO_ZERO_DATE)
 
375
        ! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
366
376
    {
367
377
      alter_info->datetime_field= def;
368
378
      alter_info->error_if_not_empty= true;
382
392
      }
383
393
      if (! find)
384
394
      {
385
 
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
 
395
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
386
396
        goto err;
387
397
      }
388
398
      find_it.after(def); /* Put element after this */
409
419
    my_error(ER_BAD_FIELD_ERROR,
410
420
             MYF(0),
411
421
             alter_info->alter_list.head()->name,
412
 
             table->s->table_name.str);
 
422
             table->getMutableShare()->getTableName());
413
423
    goto err;
414
424
  }
415
425
  if (! new_create_list.elements)
424
434
    Collect all keys which isn't in drop list. Add only those
425
435
    for which some fields exists.
426
436
  */
427
 
  for (uint32_t i= 0; i < table->s->keys; i++, key_info++)
 
437
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++, key_info++)
428
438
  {
429
439
    char *key_name= key_info->name;
430
440
    AlterDrop *drop;
441
451
      continue;
442
452
    }
443
453
 
444
 
    KEY_PART_INFO *key_part= key_info->key_part;
 
454
    KeyPartInfo *key_part= key_info->key_part;
445
455
    key_parts.empty();
446
456
    for (uint32_t j= 0; j < key_info->key_parts; j++, key_part++)
447
457
    {
558
568
  }
559
569
 
560
570
  if (not table_message.options().has_comment()
561
 
      && table->s->hasComment())
562
 
    table_options->set_comment(table->s->getComment());
 
571
      && table->getMutableShare()->hasComment())
 
572
    table_options->set_comment(table->getMutableShare()->getComment());
563
573
 
564
 
  if (table->s->tmp_table)
 
574
  if (table->getShare()->getType())
565
575
  {
566
576
    table_message.set_type(message::Table::TEMPORARY);
567
577
  }
570
580
 
571
581
  table_message.set_update_timestamp(time(NULL));
572
582
 
573
 
  if (not table_message.options().has_comment()
574
 
      && table->s->hasComment())
575
 
    table_options->set_comment(table->s->getComment());
576
 
 
577
583
  rc= false;
578
584
  alter_info->create_list.swap(new_create_list);
579
585
  alter_info->key_list.swap(new_key_list);
580
586
err:
 
587
 
 
588
  size_t num_engine_options= table_message.engine().options_size();
 
589
  size_t original_num_engine_options= original_proto.engine().options_size();
 
590
  for (size_t x= 0; x < original_num_engine_options; ++x)
 
591
  {
 
592
    bool found= false;
 
593
 
 
594
    for (size_t y= 0; y < num_engine_options; ++y)
 
595
    {
 
596
      found= not table_message.engine().options(y).name().compare(original_proto.engine().options(x).name());
 
597
      
 
598
      if (found)
 
599
        break;
 
600
    }
 
601
 
 
602
    if (not found)
 
603
    {
 
604
      message::Engine::Option *opt= table_message.mutable_engine()->add_options();
 
605
 
 
606
      opt->set_name(original_proto.engine().options(x).name());
 
607
      opt->set_state(original_proto.engine().options(x).state());
 
608
    }
 
609
  }
 
610
 
581
611
  return rc;
582
612
}
583
613
 
619
649
    goto err;
620
650
 
621
651
  /* The ALTER Table is always in its own transaction */
622
 
  error= transaction_services.ha_autocommit_or_rollback(session, false);
 
652
  error= transaction_services.autocommitOrRollback(session, false);
623
653
  if (! session->endActiveTransaction())
624
654
    error=1;
625
655
  if (error)
627
657
  write_bin_log(session, session->query.c_str());
628
658
 
629
659
err:
630
 
  (void) transaction_services.ha_autocommit_or_rollback(session, error);
 
660
  (void) transaction_services.autocommitOrRollback(session, error);
631
661
  session->tablespace_op=false;
632
662
 
633
663
  if (error == 0)
655
685
    false  OK
656
686
    true   Error
657
687
*/
658
 
static bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
659
 
                             enum enum_enable_or_disable keys_onoff)
 
688
static bool alter_table_manage_keys(Session *session,
 
689
                                    Table *table, int indexes_were_disabled,
 
690
                                    enum enum_enable_or_disable keys_onoff)
660
691
{
661
692
  int error= 0;
662
693
  switch (keys_onoff) {
664
695
    error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
665
696
    break;
666
697
  case LEAVE_AS_IS:
667
 
    if (!indexes_were_disabled)
 
698
    if (not indexes_were_disabled)
668
699
      break;
669
700
    /* fall-through: disabled indexes */
670
701
  case DISABLE:
673
704
 
674
705
  if (error == HA_ERR_WRONG_COMMAND)
675
706
  {
676
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
707
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
677
708
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
678
 
                        table->s->table_name.str);
 
709
                        table->getMutableShare()->getTableName());
679
710
    error= 0;
680
711
  } else if (error)
681
712
    table->print_error(error, MYF(0));
718
749
        /* Table will be closed by Session::executeCommand() */
719
750
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
720
751
 
721
 
        pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
 
752
        LOCK_open.lock(); /* ALTER TABLe */
722
753
        session.unlink_open_table(name_lock);
723
 
        pthread_mutex_unlock(&LOCK_open);
 
754
        LOCK_open.unlock();
724
755
 
725
756
        return false;
726
757
      }
777
808
                                 TableIdentifier &original_table_identifier,
778
809
                                 TableIdentifier &new_table_identifier,
779
810
                                 HA_CREATE_INFO *create_info,
 
811
                                 const message::Table &original_proto,
780
812
                                 message::Table &create_proto,
781
813
                                 TableList *table_list,
782
814
                                 AlterInfo *alter_info,
784
816
                                 order_st *order,
785
817
                                 bool ignore)
786
818
{
787
 
  Table *new_table= NULL;
788
819
  int error= 0;
789
820
  char tmp_name[80];
790
821
  char old_name[32];
791
822
  ha_rows copied= 0;
792
823
  ha_rows deleted= 0;
793
824
 
794
 
  message::Table *original_table_definition= table->s->getTableProto();
795
 
 
796
825
  session->set_proc_info("init");
797
826
 
798
827
  table->use_all_columns();
800
829
  plugin::StorageEngine *new_engine;
801
830
  plugin::StorageEngine *original_engine;
802
831
 
803
 
  original_engine= table->s->getEngine();
 
832
  original_engine= table->getMutableShare()->getEngine();
804
833
 
805
834
  if (not create_info->db_type)
806
835
  {
833
862
    return true;
834
863
  }
835
864
 
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
 
 
845
865
  session->set_proc_info("setup");
846
866
 
847
867
  /*
855
875
    tmp.reset(ALTER_KEYS_ONOFF);
856
876
    tmp&= alter_info->flags;
857
877
 
858
 
    if (! (tmp.any()) && ! table->s->tmp_table) // no need to touch frm
 
878
    if (! (tmp.any()) && ! table->getShare()->getType()) // no need to touch frm
859
879
    {
860
880
      switch (alter_info->keys_onoff)
861
881
      {
871
891
          while the fact that the table is still open gives us protection
872
892
          from concurrent DDL statements.
873
893
        */
874
 
        pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
 
894
        LOCK_open.lock(); /* DDL wait for/blocker */
875
895
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
876
 
        pthread_mutex_unlock(&LOCK_open);
 
896
        LOCK_open.unlock();
877
897
        error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
878
898
        /* COND_refresh will be signaled in close_thread_tables() */
879
899
        break;
880
900
      case DISABLE:
881
 
        pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
 
901
        LOCK_open.lock(); /* DDL wait for/blocker */
882
902
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
883
 
        pthread_mutex_unlock(&LOCK_open);
 
903
        LOCK_open.unlock();
884
904
        error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
885
905
        /* COND_refresh will be signaled in close_thread_tables() */
886
906
        break;
895
915
        error= 0;
896
916
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
897
917
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
898
 
                            table->alias);
 
918
                            table->getAlias());
899
919
      }
900
920
 
901
 
      pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
 
921
      LOCK_open.lock(); /* Lock to remove all instances of table from table cache before ALTER */
902
922
      /*
903
923
        Unlike to the above case close_cached_table() below will remove ALL
904
924
        instances of Table from table cache (it will also remove table lock
931
951
        }
932
952
        else
933
953
        {
934
 
          if (mysql_rename_table(original_engine, original_table_identifier, new_table_identifier, 0))
 
954
          if (mysql_rename_table(*session, original_engine, original_table_identifier, new_table_identifier))
935
955
          {
936
956
            error= -1;
937
957
          }
943
963
        error= 0;
944
964
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
945
965
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
946
 
                            table->alias);
 
966
                            table->getAlias());
947
967
      }
948
968
 
949
969
      if (error == 0)
957
977
        error= -1;
958
978
      }
959
979
 
960
 
      pthread_mutex_unlock(&LOCK_open);
 
980
      LOCK_open.unlock();
961
981
      table_list->table= NULL;
962
982
 
963
983
      return error;
967
987
  /* We have to do full alter table. */
968
988
  new_engine= create_info->db_type;
969
989
 
970
 
  if (mysql_prepare_alter_table(session, table, create_info, create_proto, alter_info))
 
990
  if (mysql_prepare_alter_table(session, table, create_info, original_proto, create_proto, alter_info))
971
991
  {
972
992
    return true;
973
993
  }
997
1017
  }
998
1018
 
999
1019
  /* Open the table so we need to copy the data to it. */
1000
 
  new_table= open_alter_table(session, table, new_table_as_temporary);
 
1020
  Table *new_table= open_alter_table(session, table, new_table_as_temporary);
 
1021
 
1001
1022
 
1002
1023
  if (not new_table)
1003
1024
  {
1007
1028
 
1008
1029
  /* Copy the data if necessary. */
1009
1030
  {
1010
 
    session->count_cuted_fields= CHECK_FIELD_WARN;      // calc cuted fields
 
1031
    /* We must not ignore bad input! */
 
1032
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;    // calc cuted fields
1011
1033
    session->cuted_fields= 0L;
1012
1034
    session->set_proc_info("copy to tmp table");
1013
1035
    copied= deleted= 0;
1015
1037
    /* We don't want update TIMESTAMP fields during ALTER Table. */
1016
1038
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1017
1039
    new_table->next_number_field= new_table->found_next_number_field;
1018
 
    error= copy_data_between_tables(table,
 
1040
    error= copy_data_between_tables(session,
 
1041
                                    table,
1019
1042
                                    new_table,
1020
1043
                                    alter_info->create_list,
1021
1044
                                    ignore,
1027
1050
                                    alter_info->error_if_not_empty);
1028
1051
 
1029
1052
    /* We must not ignore bad input! */
1030
 
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
1053
    assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
1031
1054
  }
1032
1055
 
1033
1056
  /* Now we need to resolve what just happened with the data copy. */
1091
1114
          Note that MERGE tables do not have their children attached here.
1092
1115
        */
1093
1116
        new_table->intern_close_table();
1094
 
        free(new_table);
 
1117
        if (new_table->hasShare())
 
1118
        {
 
1119
          delete new_table->s;
 
1120
          new_table->s= NULL;
 
1121
        }
 
1122
 
 
1123
        delete new_table;
1095
1124
      }
1096
1125
 
1097
 
      pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
 
1126
      LOCK_open.lock(); /* ALTER TABLE */
1098
1127
 
1099
1128
      quick_rm_table(*session, new_table_as_temporary);
1100
 
      pthread_mutex_unlock(&LOCK_open);
 
1129
      LOCK_open.unlock();
1101
1130
 
1102
1131
      return true;
1103
1132
    }
1116
1145
    session->close_temporary_table(table);
1117
1146
 
1118
1147
    /* Should pass the 'new_name' as we store table name in the cache */
1119
 
    if (new_table->renameAlterTemporaryTable(new_table_identifier))
1120
 
    {
1121
 
      session->close_temporary_table(new_table);
1122
 
 
1123
 
      return true;
1124
 
    }
 
1148
    new_table->getMutableShare()->setIdentifier(new_table_identifier);
1125
1149
 
1126
1150
    new_table_identifier.setPath(new_table_as_temporary.getPath());
1127
1151
 
1128
 
    if (mysql_rename_table(new_engine, new_table_as_temporary, new_table_identifier, FN_FROM_IS_TMP) != 0)
 
1152
    if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1129
1153
    {
1130
1154
      return true;
1131
1155
    }
1140
1164
        Note that MERGE tables do not have their children attached here.
1141
1165
      */
1142
1166
      new_table->intern_close_table();
1143
 
      free(new_table);
 
1167
 
 
1168
      if (new_table->hasShare())
 
1169
      {
 
1170
        delete new_table->s;
 
1171
        new_table->s= NULL;
 
1172
      }
 
1173
 
 
1174
      delete new_table;
1144
1175
    }
1145
1176
 
1146
 
    pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
 
1177
    LOCK_open.lock(); /* ALTER TABLE */
1147
1178
 
1148
1179
    /*
1149
1180
      Data is copied. Now we:
1182
1213
      compare_table(). Then, we need one additional call to
1183
1214
    */
1184
1215
    TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1185
 
                                           old_name, message::Table::TEMPORARY);
 
1216
                                           old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
 
1217
                                         message::Table::TEMPORARY);
1186
1218
 
1187
 
    if (mysql_rename_table(original_engine, original_table_identifier, original_table_to_drop, FN_TO_IS_TMP))
 
1219
    if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1188
1220
    {
1189
1221
      error= 1;
1190
1222
      quick_rm_table(*session, new_table_as_temporary);
1191
1223
    }
1192
1224
    else
1193
1225
    {
1194
 
      if (mysql_rename_table(new_engine, new_table_as_temporary, new_table_identifier, FN_FROM_IS_TMP) != 0)
 
1226
      if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1195
1227
      {
1196
1228
        /* Try to get everything back. */
1197
1229
        error= 1;
1200
1232
 
1201
1233
        quick_rm_table(*session, new_table_as_temporary);
1202
1234
 
1203
 
        mysql_rename_table(original_engine, original_table_to_drop, original_table_identifier, FN_FROM_IS_TMP);
 
1235
        mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1204
1236
      }
1205
1237
      else
1206
1238
      {
1216
1248
        from list of open tables list and table cache.
1217
1249
      */
1218
1250
      session->unlink_open_table(table);
1219
 
      pthread_mutex_unlock(&LOCK_open);
 
1251
      LOCK_open.unlock();
1220
1252
 
1221
1253
      return true;
1222
1254
    }
1223
1255
 
1224
 
    pthread_mutex_unlock(&LOCK_open);
 
1256
    LOCK_open.unlock();
1225
1257
 
1226
1258
    session->set_proc_info("end");
1227
1259
 
1253
1285
                 TableIdentifier &original_table_identifier,
1254
1286
                 TableIdentifier &new_table_identifier,
1255
1287
                 HA_CREATE_INFO *create_info,
 
1288
                 const message::Table &original_proto,
1256
1289
                 message::Table &create_proto,
1257
1290
                 TableList *table_list,
1258
1291
                 AlterInfo *alter_info,
1293
1326
                                original_table_identifier,
1294
1327
                                new_table_identifier,
1295
1328
                                create_info,
 
1329
                                original_proto,
1296
1330
                                create_proto,
1297
1331
                                table_list,
1298
1332
                                alter_info,
1302
1336
 
1303
1337
    if (name_lock)
1304
1338
    {
1305
 
      pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
 
1339
      LOCK_open.lock(); /* ALTER TABLe */
1306
1340
      session->unlink_open_table(name_lock);
1307
 
      pthread_mutex_unlock(&LOCK_open);
 
1341
      LOCK_open.unlock();
1308
1342
    }
1309
1343
  }
1310
1344
 
1313
1347
/* alter_table */
1314
1348
 
1315
1349
static int
1316
 
copy_data_between_tables(Table *from, Table *to,
 
1350
copy_data_between_tables(Session *session,
 
1351
                         Table *from, Table *to,
1317
1352
                         List<CreateField> &create,
1318
1353
                         bool ignore,
1319
1354
                         uint32_t order_num, order_st *order,
1325
1360
  int error= 0;
1326
1361
  CopyField *copy,*copy_end;
1327
1362
  ulong found_count,delete_count;
1328
 
  Session *session= current_session;
1329
1363
  uint32_t length= 0;
1330
 
  SORT_FIELD *sortorder;
1331
 
  READ_RECORD info;
 
1364
  SortField *sortorder;
 
1365
  ReadRecord info;
1332
1366
  TableList   tables;
1333
1367
  List<Item>   fields;
1334
1368
  List<Item>   all_fields;
1344
1378
  */
1345
1379
  TransactionServices &transaction_services= TransactionServices::singleton();
1346
1380
 
1347
 
  if (!(copy= new CopyField[to->s->fields]))
 
1381
  /* 
 
1382
   * LP Bug #552420 
 
1383
   *
 
1384
   * Since open_temporary_table() doesn't invoke mysql_lock_tables(), we
 
1385
   * don't get the usual automatic call to StorageEngine::startStatement(), so
 
1386
   * we manually call it here...
 
1387
   */
 
1388
  to->s->getEngine()->startStatement(session);
 
1389
 
 
1390
  if (!(copy= new CopyField[to->getShare()->sizeFields()]))
1348
1391
    return -1;
1349
1392
 
1350
1393
  if (to->cursor->ha_external_lock(session, F_WRLCK))
1351
1394
    return -1;
1352
1395
 
1353
1396
  /* We need external lock before we can disable/enable keys */
1354
 
  alter_table_manage_keys(to, from->cursor->indexes_are_disabled(), keys_onoff);
 
1397
  alter_table_manage_keys(session, to, from->cursor->indexes_are_disabled(), keys_onoff);
1355
1398
 
1356
1399
  /* We can abort alter table for any table type */
1357
1400
  session->abort_on_warning= !ignore;
1362
1405
  List_iterator<CreateField> it(create);
1363
1406
  CreateField *def;
1364
1407
  copy_end=copy;
1365
 
  for (Field **ptr=to->field ; *ptr ; ptr++)
 
1408
  for (Field **ptr= to->getFields(); *ptr ; ptr++)
1366
1409
  {
1367
1410
    def=it++;
1368
1411
    if (def->field)
1379
1422
 
1380
1423
  if (order)
1381
1424
  {
1382
 
    if (to->s->primary_key != MAX_KEY && to->cursor->primary_key_is_clustered())
 
1425
    if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1383
1426
    {
1384
1427
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
1385
1428
      snprintf(warn_buff, sizeof(warn_buff),
1386
1429
               _("order_st BY ignored because there is a user-defined clustered "
1387
1430
                 "index in the table '%-.192s'"),
1388
 
               from->s->table_name.str);
 
1431
               from->getMutableShare()->getTableName());
1389
1432
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1390
1433
                   warn_buff);
1391
1434
    }
1392
1435
    else
1393
1436
    {
1394
1437
      from->sort.io_cache= new internal::IO_CACHE;
1395
 
      memset(from->sort.io_cache, 0, sizeof(internal::IO_CACHE));
1396
1438
 
1397
1439
      memset(&tables, 0, sizeof(tables));
1398
1440
      tables.table= from;
1399
 
      tables.alias= tables.table_name= from->s->table_name.str;
1400
 
      tables.db= const_cast<char *>(from->s->getSchemaName());
 
1441
      tables.alias= tables.table_name= const_cast<char *>(from->getMutableShare()->getTableName());
 
1442
      tables.db= const_cast<char *>(from->getMutableShare()->getSchemaName());
1401
1443
      error= 1;
1402
1444
 
1403
1445
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1416
1458
 
1417
1459
  /* Tell handler that we have values for all columns in the to table */
1418
1460
  to->use_all_columns();
1419
 
  init_read_record(&info, session, from, (optimizer::SqlSelect *) 0, 1,1);
 
1461
  info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
1420
1462
  if (ignore)
1421
1463
    to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1422
1464
  session->row_count= 0;
1449
1491
      copy_ptr->do_copy(copy_ptr);
1450
1492
    }
1451
1493
    prev_insert_id= to->cursor->next_insert_id;
1452
 
    error= to->cursor->ha_write_row(to->record[0]);
 
1494
    error= to->cursor->insertRecord(to->record[0]);
1453
1495
    to->auto_increment_field_not_null= false;
 
1496
 
1454
1497
    if (error)
1455
1498
    { 
1456
1499
      if (!ignore ||
1463
1506
      delete_count++;
1464
1507
    }
1465
1508
    else
 
1509
    {
1466
1510
      found_count++;
 
1511
    }
1467
1512
  }
1468
 
  end_read_record(&info);
 
1513
 
 
1514
  info.end_read_record();
1469
1515
  from->free_io_cache();
1470
1516
  delete [] copy;                               // This is never 0
1471
1517
 
1480
1526
    Ensure that the new table is saved properly to disk so that we
1481
1527
    can do a rename
1482
1528
  */
1483
 
  if (transaction_services.ha_autocommit_or_rollback(session, false))
 
1529
  if (transaction_services.autocommitOrRollback(session, false))
1484
1530
    error=1;
1485
1531
  if (! session->endActiveTransaction())
1486
1532
    error=1;
1493
1539
  to->cursor->ha_release_auto_increment();
1494
1540
  if (to->cursor->ha_external_lock(session,F_UNLCK))
1495
1541
    error=1;
 
1542
 
1496
1543
  return(error > 0 ? -1 : 0);
1497
1544
}
1498
1545
 
1511
1558
  */
1512
1559
  create_proto.set_name(identifier.getTableName());
1513
1560
 
1514
 
  message::Table::StorageEngine *protoengine;
1515
 
  protoengine= create_proto.mutable_engine();
1516
 
  protoengine->set_name(create_info->db_type->getName());
 
1561
  create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1517
1562
 
1518
1563
  error= mysql_create_table(session,
1519
1564
                            identifier,
1527
1572
  Table *new_table;
1528
1573
 
1529
1574
  /* Open the table so we need to copy the data to it. */
1530
 
  if (table->s->tmp_table)
 
1575
  if (table->getShare()->getType())
1531
1576
  {
1532
1577
    TableList tbl;
1533
1578
    tbl.db= const_cast<char *>(identifier.getSchemaName().c_str());