28 #include <drizzled/lock.h>
29 #include <drizzled/session.h>
30 #include <drizzled/statement/alter_table.h>
31 #include <drizzled/charset.h>
32 #include <drizzled/gettext.h>
33 #include <drizzled/data_home.h>
35 #include <drizzled/table_proto.h>
36 #include <drizzled/optimizer/range.h>
37 #include <drizzled/time_functions.h>
38 #include <drizzled/records.h>
39 #include <drizzled/pthread_globals.h>
40 #include <drizzled/internal/my_sys.h>
41 #include <drizzled/internal/iocache.h>
42 #include <drizzled/plugin/storage_engine.h>
43 #include <drizzled/copy_field.h>
44 #include <drizzled/transaction_services.h>
45 #include <drizzled/filesort.h>
46 #include <drizzled/message.h>
47 #include <drizzled/message/alter_table.pb.h>
48 #include <drizzled/alter_column.h>
49 #include <drizzled/alter_info.h>
50 #include <drizzled/util/test.h>
51 #include <drizzled/open_tables_state.h>
52 #include <drizzled/table/cache.h>
53 #include <drizzled/create_field.h>
59 extern pid_t current_pid;
61 static int copy_data_between_tables(Session *session,
62 Table *from,Table *to,
63 List<CreateField> &create,
69 message::AlterTable &alter_table_message,
70 bool error_if_not_empty);
74 HA_CREATE_INFO *create_info,
75 const message::Table &original_proto,
76 message::Table &table_message,
77 message::AlterTable &alter_table_message,
78 AlterInfo *alter_info);
80 static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier);
82 static int apply_online_alter_keys_onoff(Session *session,
84 const message::AlterTable::AlterKeysOnOff &op);
86 static int apply_online_rename_table(Session *session,
88 plugin::StorageEngine *original_engine,
89 identifier::Table &original_table_identifier,
90 identifier::Table &new_table_identifier,
91 const message::AlterTable::RenameTable &alter_operation);
95 AlterTable::AlterTable(Session *in_session, Table_ident *) :
96 CreateTable(in_session)
98 set_command(SQLCOM_ALTER_TABLE);
106 TableList *all_tables= lex().query_tables;
107 assert(first_table == all_tables && first_table != 0);
108 Select_Lex *select_lex= &lex().select_lex;
110 is_engine_set= not createTableMessage().engine().name().empty();
114 create_info().db_type=
115 plugin::StorageEngine::findByName(session(), createTableMessage().engine().name());
117 if (create_info().db_type == NULL)
119 my_error(createTableMessage().engine().name(), ER_UNKNOWN_STORAGE_ENGINE, MYF(0));
126 assert(select_lex->db);
129 message::table::shared_ptr original_table_message;
131 identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
132 if (not (original_table_message= plugin::StorageEngine::getTableMessage(session(), identifier)))
134 my_error(ER_BAD_TABLE_ERROR, identifier);
138 if (not create_info().db_type)
140 create_info().db_type=
141 plugin::StorageEngine::findByName(session(), original_table_message->engine().name());
143 if (not create_info().db_type)
145 my_error(ER_BAD_TABLE_ERROR, identifier);
151 if (not validateCreateTableOption())
154 if (session().inTransaction())
156 my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
160 if (session().wait_if_global_read_lock(0, 1))
164 if (original_table_message->type() == message::Table::STANDARD )
166 identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
167 identifier::Table new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
168 lex().name.data() ? lex().name.data() : first_table->getTableName());
170 res= alter_table(&session(),
174 *original_table_message,
175 createTableMessage(),
178 select_lex->order_list.size(),
179 (
Order *) select_lex->order_list.first,
184 identifier::Table catch22(first_table->getSchemaName(), first_table->getTableName());
185 Table *table= session().open_tables.find_temporary_table(catch22);
188 identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
189 identifier::Table new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
190 lex().name.data() ? lex().name.data() : first_table->getTableName(),
191 table->getMutableShare()->getPath());
193 res= alter_table(&session(),
197 *original_table_message,
198 createTableMessage(),
201 select_lex->order_list.size(),
202 (
Order *) select_lex->order_list.first,
211 session().startWaitingGlobalReadLock();
265 uint32_t used_fields= create_info->used_fields;
266 vector<string> drop_keys;
267 vector<string> drop_columns;
268 vector<string> drop_fkeys;
272 for (
int operationnr= 0; operationnr < alter_table_message.operations_size();
276 alter_table_message.operations(operationnr);
278 switch (operation.operation())
280 case message::AlterTable::AlterTableOperation::DROP_KEY:
281 drop_keys.push_back(operation.drop_name());
283 case message::AlterTable::AlterTableOperation::DROP_COLUMN:
284 drop_columns.push_back(operation.drop_name());
286 case message::AlterTable::AlterTableOperation::DROP_FOREIGN_KEY:
287 drop_fkeys.push_back(operation.drop_name());
297 if (not (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
298 create_info->default_table_charset= table->getShare()->table_charset;
303 table->
cursor->info(HA_STATUS_AUTO);
304 create_info->auto_increment_value= table->
cursor->stats.auto_increment_value;
305 if (create_info->auto_increment_value != original_proto.options().auto_increment_value())
306 table_options->set_has_user_set_auto_increment_value(
false);
309 table->restoreRecordAsDefault();
315 for (
Field **f_ptr= table->getFields(); (field= *f_ptr); f_ptr++)
318 vector<string>::iterator it= drop_columns.begin();
319 while (it != drop_columns.end())
321 if (not system_charset_info->strcasecmp(field->
field_name, it->c_str()))
324 if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
325 not (used_fields & HA_CREATE_USED_AUTO))
327 create_info->auto_increment_value= 0;
328 create_info->used_fields|= HA_CREATE_USED_AUTO;
335 if (it != drop_columns.end())
337 drop_columns.erase(it);
347 while ((def= def_it++))
360 new_create_list.push_back(def);
371 new_create_list.push_back(def);
372 AlterInfo::alter_list_t::iterator alter(alter_info->alter_list.begin());
374 for (; alter != alter_info->alter_list.end(); alter++)
376 if (not system_charset_info->strcasecmp(field->
field_name, alter->name))
380 if (alter != alter_info->alter_list.end())
382 def->setDefaultValue(alter->def, NULL);
384 alter_info->alter_list.erase(alter);
391 while ((def= def_it++))
393 if (def->
change && ! def->field)
395 my_error(ER_BAD_FIELD_ERROR, MYF(0), def->
change, table->getMutableShare()->getTableName());
401 if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->
change)
403 alter_info->error_if_not_empty=
true;
407 new_create_list.push_back(def);
409 else if (def->
after == first_keyword)
411 new_create_list.push_front(def);
418 while ((find= find_it++))
426 my_error(ER_BAD_FIELD_ERROR, MYF(0), def->
after, table->getMutableShare()->getTableName());
442 if (alter_table_message.build_method() == message::AlterTable::BUILD_ONLINE)
444 my_error(*session->getQueryString(), ER_NOT_SUPPORTED_YET);
450 if (not alter_info->alter_list.empty())
452 my_error(ER_BAD_FIELD_ERROR, MYF(0), alter_info->alter_list.front().name, table->getMutableShare()->getTableName());
456 if (new_create_list.is_empty())
458 my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), MYF(0));
467 for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++, key_info++)
469 const char *key_name= key_info->name;
471 vector<string>::iterator it= drop_keys.begin();
472 while (it != drop_keys.end())
474 if (not system_charset_info->strcasecmp(key_name, it->c_str()))
479 if (it != drop_keys.end())
487 for (uint32_t j= 0; j < key_info->key_parts; j++, key_part++)
489 if (not key_part->field)
492 const char *key_part_name= key_part->field->
field_name;
495 while ((cfield= field_it++))
499 if (not system_charset_info->strcasecmp(key_part_name, cfield->
change))
502 else if (not system_charset_info->strcasecmp(key_part_name, cfield->
field_name))
509 uint32_t key_part_length= key_part->length;
526 (cfield->field->field_length == key_part_length) ||
528 (cfield->length < key_part_length / key_part->field->charset()->mbmaxlen)))
531 key_part_length/= key_part->field->charset()->mbmaxlen;
534 if (key_parts.size())
537 key_create_info.algorithm= key_info->algorithm;
539 if (key_info->flags & HA_USES_BLOCK_SIZE)
540 key_create_info.block_size= key_info->block_size;
542 if (key_info->flags & HA_USES_COMMENT)
543 key_create_info.comment= key_info->comment;
545 Key::Keytype key_type= key_info->flags & HA_NOSAME
546 ? (is_primary_key(key_name) ? Key::PRIMARY : Key::UNIQUE)
548 new_key_list.push_back(
new Key(key_type,
str_ref(key_name), &key_create_info, test(key_info->flags & HA_GENERATED_KEY), key_parts));
553 for (int32_t j= 0; j < original_proto.fk_constraint_size(); j++)
555 vector<string>::iterator it= drop_fkeys.begin();
556 while (it != drop_fkeys.end())
558 if (! system_charset_info->strcasecmp(original_proto.fk_constraint(j).name().c_str(), it->c_str()))
565 if (it != drop_fkeys.end())
567 drop_fkeys.erase(it);
572 *pfkey= original_proto.fk_constraint(j);
578 while ((key= key_it++))
580 if (key->type == Key::FOREIGN_KEY)
582 if (((
Foreign_key *)key)->validate(new_create_list))
588 add_foreign_key_to_table_message(&table_message,
598 if (key->type != Key::FOREIGN_KEY)
599 new_key_list.push_back(key);
601 if (key->name.data() && is_primary_key(key->name.data()))
603 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.data());
610 for (
int j= 0; j < table_message.fk_constraint_size(); j++)
612 if (! table_message.fk_constraint(j).has_name())
614 std::string name(table->getMutableShare()->getTableName());
617 name.append(
"_ibfk_");
618 snprintf(number,
sizeof(number),
"%d", j+1);
622 pfkey->set_name(name);
626 if (drop_keys.size())
628 my_error(ER_CANT_DROP_FIELD_OR_KEY,
630 drop_keys.front().c_str());
634 if (drop_columns.size())
636 my_error(ER_CANT_DROP_FIELD_OR_KEY,
638 drop_columns.front().c_str());
642 if (drop_fkeys.size())
644 my_error(ER_CANT_DROP_FIELD_OR_KEY,
646 drop_fkeys.front().c_str());
650 if (not alter_info->alter_list.empty())
652 my_error(ER_CANT_DROP_FIELD_OR_KEY,
654 alter_info->alter_list.front().name);
658 if (not table_message.options().has_comment()
659 && table->getMutableShare()->hasComment())
661 table_options->set_comment(table->getMutableShare()->getComment());
664 if (table->getShare()->getType())
666 table_message.set_type(message::Table::TEMPORARY);
669 table_message.set_creation_timestamp(table->getShare()->getTableMessage()->creation_timestamp());
670 table_message.set_version(table->getShare()->getTableMessage()->version());
671 table_message.set_uuid(table->getShare()->getTableMessage()->uuid());
673 alter_info->create_list.swap(new_create_list);
674 alter_info->key_list.swap(new_key_list);
676 size_t num_engine_options= table_message.engine().options_size();
677 size_t original_num_engine_options= original_proto.engine().options_size();
678 for (
size_t x= 0; x < original_num_engine_options; ++x)
682 for (
size_t y= 0; y < num_engine_options; ++y)
684 found= not table_message.engine().options(y).name().compare(original_proto.engine().options(x).name());
694 opt->set_name(original_proto.engine().options(x).name());
695 opt->set_state(original_proto.engine().options(x).state());
699 drizzled::message::update(table_message);
705 static int discard_or_import_tablespace(Session *session,
706 TableList *table_list,
713 session->set_proc_info(
"discard_or_import_tablespace");
719 session->setDoingTablespaceOperation(
true);
720 Table* table= session->openTableLock(table_list, TL_WRITE);
723 session->setDoingTablespaceOperation(
false);
729 error= table->cursor->ha_discard_or_import_tablespace(discard);
731 session->set_proc_info(
"end");
738 if (not session->endActiveTransaction())
745 *session->getQueryString(),
751 session->setDoingTablespaceOperation(
false);
759 table->print_error(error, MYF(0));
779 Table *table,
int indexes_were_disabled,
783 if (alter_table_message.has_alter_keys_onoff()
784 && alter_table_message.alter_keys_onoff().enable())
789 if ((! alter_table_message.has_alter_keys_onoff() && indexes_were_disabled)
790 || (alter_table_message.has_alter_keys_onoff()
791 && ! alter_table_message.alter_keys_onoff().enable()))
796 if (error == HA_ERR_WRONG_COMMAND)
798 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
799 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
800 table->getMutableShare()->getTableName());
805 table->print_error(error, MYF(0));
811 static bool lockTableIfDifferent(Session &session,
812 identifier::Table &original_table_identifier,
813 identifier::Table &new_table_identifier,
817 if (not (original_table_identifier == new_table_identifier))
819 if (original_table_identifier.isTmp())
821 if (session.open_tables.find_temporary_table(new_table_identifier))
823 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
829 name_lock= session.lock_table_name_if_not_cached(new_table_identifier);
832 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
839 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
842 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
843 session.unlink_open_table(name_lock);
916 if (not original_table_identifier.isValid())
919 if (not new_table_identifier.isValid())
924 table->use_all_columns();
929 original_engine= table->getMutableShare()->getEngine();
931 if (not create_info->db_type)
933 create_info->db_type= original_engine;
935 new_engine= create_info->db_type;
938 create_proto.set_schema(new_table_identifier.getSchemaName());
939 create_proto.set_type(new_table_identifier.getType());
945 if (new_engine != original_engine &&
949 my_error(ER_ROW_IS_REFERENCED, MYF(0));
954 if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
955 new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
957 my_error(ER_ILLEGAL_HA, new_table_identifier);
970 if ((alter_table_message.has_rename()
971 || alter_table_message.has_alter_keys_onoff())
972 && alter_table_message.operations_size() == 0)
980 tmp.reset(ALTER_RENAME);
981 tmp.reset(ALTER_KEYS_ONOFF);
982 tmp&= alter_info->flags;
984 if((not (tmp.any()) && not table->getShare()->getType()))
986 if (alter_table_message.has_alter_keys_onoff())
988 error= apply_online_alter_keys_onoff(session, table,
989 alter_table_message.alter_keys_onoff());
991 if (error == HA_ERR_WRONG_COMMAND)
994 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
995 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1000 if (alter_table_message.has_rename())
1002 error= apply_online_rename_table(session,
1005 original_table_identifier,
1006 new_table_identifier,
1007 alter_table_message.rename());
1009 if (error == HA_ERR_WRONG_COMMAND)
1012 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1013 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1020 TransactionServices::allocateNewTransactionId();
1022 *session->getQueryString(),
1023 *session->schema());
1026 else if (error > EE_OK)
1028 table->print_error(error, MYF(0));
1031 table_list->
table= NULL;
1037 if (alter_table_message.build_method() == message::AlterTable::BUILD_ONLINE)
1039 my_error(*session->getQueryString(), ER_NOT_SUPPORTED_YET);
1044 new_engine= create_info->db_type;
1046 if (
prepare_alter_table(session, table, create_info, original_proto, create_proto, alter_table_message, alter_info))
1051 set_table_default_charset(create_info, new_table_identifier.getSchemaName().c_str());
1053 snprintf(tmp_name,
sizeof(tmp_name),
"%s-%lx_%"PRIx64,
TMP_FILE_PREFIX, (
unsigned long) current_pid, session->thread_id);
1061 identifier::Table new_table_as_temporary(original_table_identifier.getSchemaName(),
1063 create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1064 message::Table::TEMPORARY);
1070 create_proto.set_name(new_table_as_temporary.getTableName());
1071 create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1073 error= create_table(session,
1074 new_table_as_temporary,
1075 create_info, create_proto, alter_info,
true, 0,
false);
1083 Table *new_table= open_alter_table(session, table, new_table_as_temporary);
1088 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1095 session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1101 new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1102 new_table->next_number_field= new_table->found_next_number_field;
1103 error= copy_data_between_tables(session,
1106 alter_info->create_list,
1112 alter_table_message,
1113 alter_info->error_if_not_empty);
1116 assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
1127 if (alter_info->error_if_not_empty && session->
row_count)
1129 my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1132 if (original_table_identifier.isTmp())
1137 session->open_tables.close_temporary_table(new_table);
1141 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1154 new_table->intern_close_table();
1155 if (new_table->hasShare())
1157 delete new_table->getMutableShare();
1163 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1165 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1171 else if (original_table_identifier.isTmp())
1174 if (session->open_tables.lock)
1176 session->unlockTables(session->open_tables.lock);
1177 session->open_tables.lock= 0;
1181 session->open_tables.close_temporary_table(table);
1184 new_table->getMutableShare()->setIdentifier(new_table_identifier);
1186 new_table_identifier.setPath(new_table_as_temporary.getPath());
1188 if (rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1202 new_table->intern_close_table();
1204 if (new_table->hasShare())
1206 delete new_table->getMutableShare();
1213 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1232 snprintf(old_name,
sizeof(old_name),
"%s2-%lx-%"PRIx64,
TMP_FILE_PREFIX, (
unsigned long) current_pid, session->thread_id);
1234 files_charset_info->casedn_str(old_name);
1236 wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1250 identifier::Table original_table_to_drop(original_table_identifier.getSchemaName(),
1251 old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1252 message::Table::TEMPORARY);
1254 drizzled::error_t rename_error= EE_OK;
1255 if (rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1257 error= ER_ERROR_ON_RENAME;
1258 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1262 if (rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1265 rename_error= ER_ERROR_ON_RENAME;
1267 plugin::StorageEngine::dropTable(*session, new_table_identifier);
1269 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1271 rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1275 plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1295 *session->getQueryString(),
1296 *session->schema());
1297 table_list->
table= NULL;
1311 snprintf(tmp_name,
sizeof(tmp_name), ER(ER_INSERT_INFO),
1312 (ulong) (copied + deleted), (ulong) deleted,
1314 session->
my_ok(copied + deleted, 0, 0L, tmp_name);
1318 static int apply_online_alter_keys_onoff(Session *session,
1320 const message::AlterTable::AlterKeysOnOff &op)
1336 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1337 wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1339 error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1346 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1347 wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1349 error= table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1357 static int apply_online_rename_table(Session *session,
1359 plugin::StorageEngine *original_engine,
1360 identifier::Table &original_table_identifier,
1361 identifier::Table &new_table_identifier,
1362 const message::AlterTable::RenameTable &alter_operation)
1366 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1373 if (not (original_table_identifier == new_table_identifier))
1375 assert(alter_operation.to_name() == new_table_identifier.getTableName());
1376 assert(alter_operation.to_schema() == new_table_identifier.getSchemaName());
1378 session->set_proc_info(
"rename");
1383 session->close_cached_table(table);
1394 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
1399 if (rename_table(*session, original_engine, original_table_identifier, new_table_identifier))
1408 bool alter_table(Session *session,
1409 identifier::Table &original_table_identifier,
1410 identifier::Table &new_table_identifier,
1411 HA_CREATE_INFO *create_info,
1412 const message::Table &original_proto,
1413 message::Table &create_proto,
1414 TableList *table_list,
1415 AlterInfo *alter_info,
1422 message::AlterTable *alter_table_message= session->lex().alter_table();
1424 alter_table_message->set_catalog(original_table_identifier.getCatalogName());
1425 alter_table_message->set_schema(original_table_identifier.getSchemaName());
1426 alter_table_message->set_name(original_table_identifier.getTableName());
1428 if (alter_table_message->operations_size()
1429 && (alter_table_message->operations(0).operation()
1430 == message::AlterTable::AlterTableOperation::DISCARD_TABLESPACE
1431 || alter_table_message->operations(0).operation()
1432 == message::AlterTable::AlterTableOperation::IMPORT_TABLESPACE))
1434 bool discard= (alter_table_message->operations(0).operation() ==
1435 message::AlterTable::AlterTableOperation::DISCARD_TABLESPACE);
1437 return discard_or_import_tablespace(session, table_list, discard);
1440 session->set_proc_info(
"init");
1442 if (not (table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
1445 session->set_proc_info(
"gained write lock on table");
1452 Table *name_lock= NULL;
1454 if (not lockTableIfDifferent(*session, original_table_identifier, new_table_identifier, name_lock))
1461 original_table_identifier,
1462 new_table_identifier,
1466 *alter_table_message,
1475 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1476 session->unlink_open_table(name_lock);
1485 copy_data_between_tables(Session *session,
1486 Table *from, Table *to,
1487 List<CreateField> &create,
1489 uint32_t order_num, Order *order,
1492 message::AlterTable &alter_table_message,
1493 bool error_if_not_empty)
1496 CopyField *copy,*copy_end;
1497 ulong found_count,delete_count;
1499 SortField *sortorder;
1503 List<Item> all_fields;
1504 ha_rows examined_rows;
1505 bool auto_increment_field_copied= 0;
1522 to->getMutableShare()->getEngine()->startStatement(session);
1524 copy=
new CopyField[to->getShare()->sizeFields()];
1526 if (to->cursor->ha_external_lock(session, F_WRLCK))
1531 alter_table_message);
1534 session->setAbortOnWarning(not ignore);
1536 from->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1537 to->cursor->ha_start_bulk_insert(from->cursor->stats.records);
1539 List<CreateField>::iterator it(create.begin());
1541 for (Field **ptr= to->getFields(); *ptr ; ptr++)
1543 CreateField* def=it++;
1546 if (*ptr == to->next_number_field)
1547 auto_increment_field_copied=
true;
1549 (copy_end++)->set(*ptr,def->field,0);
1554 found_count=delete_count=0;
1560 if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1562 char warn_buff[DRIZZLE_ERRMSG_SIZE];
1563 snprintf(warn_buff,
sizeof(warn_buff),
1564 _(
"order_st BY ignored because there is a user-defined clustered "
1565 "index in the table '%-.192s'"),
1566 from->getMutableShare()->getTableName());
1567 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1572 FileSort filesort(*session);
1573 from->sort.io_cache=
new internal::io_cache_st;
1576 tables.setTableName(from->getMutableShare()->getTableName());
1577 tables.alias= tables.getTableName();
1578 tables.setSchemaName(from->getMutableShare()->getSchemaName());
1581 session->lex().select_lex.setup_ref_array(session, order_num);
1582 if (
setup_order(session, session->lex().select_lex.ref_pointer_array, &tables, fields, all_fields, order))
1584 sortorder= make_unireg_sortorder(order, &length, NULL);
1585 if ((from->sort.found_records= filesort.run(from, sortorder, length, (optimizer::SqlSelect *) 0, HA_POS_ERROR, 1, examined_rows)) == HA_POS_ERROR)
1591 to->use_all_columns();
1593 error= info.init_read_record(session, from, NULL, 1,
true);
1596 to->print_error(errno, MYF(0));
1603 to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1606 session->row_count= 0;
1607 to->restoreRecordAsDefault();
1608 while (not (error=info.read_record(&info)))
1610 if (session->getKilled())
1612 session->send_kill_message();
1616 session->row_count++;
1618 if (error_if_not_empty)
1623 if (to->next_number_field)
1625 if (auto_increment_field_copied)
1626 to->auto_increment_field_not_null=
true;
1628 to->next_number_field->reset();
1631 for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1633 if (not copy->to_field->hasDefault() and copy->from_null_ptr and *copy->from_null_ptr & copy->from_bit)
1635 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1636 ER_WARN_DATA_TRUNCATED, 1);
1637 copy->to_field->reset();
1642 copy_ptr->do_copy(copy_ptr);
1650 prev_insert_id= to->cursor->next_insert_id;
1651 error= to->cursor->insertRecord(to->record[0]);
1652 to->auto_increment_field_not_null=
false;
1656 if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1658 to->print_error(error, MYF(0));
1661 to->cursor->restore_auto_increment(prev_insert_id);
1670 info.end_read_record();
1671 from->free_io_cache();
1674 if (to->cursor->ha_end_bulk_insert() && error <= 0)
1676 to->print_error(errno, MYF(0));
1679 to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1688 if (not session->endActiveTransaction())
1693 session->setAbortOnWarning(
false);
1694 from->free_io_cache();
1695 *copied= found_count;
1696 *deleted=delete_count;
1697 to->cursor->ha_release_auto_increment();
1699 if (to->cursor->ha_external_lock(session, F_UNLCK))
1704 return error > 0 ? -1 : 0;
1707 static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier)
1710 if (table->getShare()->getType())
1713 tbl.setSchemaName(identifier.getSchemaName().c_str());
1714 tbl.alias= identifier.getTableName().c_str();
1715 tbl.setTableName(identifier.getTableName().c_str());
1718 return session->openTable(&tbl, NULL, DRIZZLE_LOCK_IGNORE_FLUSH);
1723 return session->open_temporary_table(identifier,
false);