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>
54 #include <drizzled/catalog/instance.h>
60 extern pid_t current_pid;
62 static int copy_data_between_tables(Session *session,
63 Table *from,Table *to,
64 List<CreateField> &create,
70 message::AlterTable &alter_table_message,
71 bool error_if_not_empty);
75 HA_CREATE_INFO *create_info,
76 const message::Table &original_proto,
77 message::Table &table_message,
78 message::AlterTable &alter_table_message,
79 AlterInfo *alter_info);
81 static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier);
83 static int apply_online_alter_keys_onoff(Session *session,
85 const message::AlterTable::AlterKeysOnOff &op);
87 static int apply_online_rename_table(Session *session,
89 plugin::StorageEngine *original_engine,
90 identifier::Table &original_table_identifier,
91 identifier::Table &new_table_identifier,
92 const message::AlterTable::RenameTable &alter_operation);
96 AlterTable::AlterTable(Session *in_session, Table_ident *) :
97 CreateTable(in_session)
99 set_command(SQLCOM_ALTER_TABLE);
107 TableList *all_tables= lex().query_tables;
108 assert(first_table == all_tables && first_table != 0);
109 Select_Lex *select_lex= &lex().select_lex;
111 is_engine_set= not createTableMessage().engine().name().empty();
115 create_info().db_type=
116 plugin::StorageEngine::findByName(session(), createTableMessage().engine().name());
118 if (create_info().db_type == NULL)
120 my_error(createTableMessage().engine().name(), ER_UNKNOWN_STORAGE_ENGINE, MYF(0));
127 assert(select_lex->db);
130 message::table::shared_ptr original_table_message;
133 first_table->getSchemaName(),
134 first_table->getTableName());
135 if (not (original_table_message= plugin::StorageEngine::getTableMessage(session(), identifier)))
137 my_error(ER_BAD_TABLE_ERROR, identifier);
141 if (not create_info().db_type)
143 create_info().db_type=
144 plugin::StorageEngine::findByName(session(), original_table_message->engine().name());
146 if (not create_info().db_type)
148 my_error(ER_BAD_TABLE_ERROR, identifier);
154 if (not validateCreateTableOption())
157 if (session().inTransaction())
159 my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
163 if (session().wait_if_global_read_lock(0, 1))
167 if (original_table_message->type() == message::Table::STANDARD )
170 first_table->getSchemaName(),
171 first_table->getTableName());
173 select_lex->db ? select_lex->db : first_table->getSchemaName(),
174 lex().name.data() ? lex().name.data() : first_table->getTableName());
176 res= alter_table(&session(),
180 *original_table_message,
181 createTableMessage(),
184 select_lex->order_list.size(),
185 (
Order *) select_lex->order_list.first,
191 first_table->getSchemaName(),
192 first_table->getTableName());
193 Table *table= session().open_tables.find_temporary_table(catch22);
197 first_table->getSchemaName(),
198 first_table->getTableName(),
199 table->getMutableShare()->getPath());
202 select_lex->db ? select_lex->db : first_table->getSchemaName(),
203 lex().name.data() ? lex().name.data() : first_table->getTableName(),
204 table->getMutableShare()->getPath());
206 res= alter_table(&session(),
210 *original_table_message,
211 createTableMessage(),
214 select_lex->order_list.size(),
215 (
Order *) select_lex->order_list.first,
224 session().startWaitingGlobalReadLock();
278 uint32_t used_fields= create_info->used_fields;
279 vector<string> drop_keys;
280 vector<string> drop_columns;
281 vector<string> drop_fkeys;
285 for (
int operationnr= 0; operationnr < alter_table_message.operations_size();
289 alter_table_message.operations(operationnr);
291 switch (operation.operation())
293 case message::AlterTable::AlterTableOperation::DROP_KEY:
294 drop_keys.push_back(operation.drop_name());
296 case message::AlterTable::AlterTableOperation::DROP_COLUMN:
297 drop_columns.push_back(operation.drop_name());
299 case message::AlterTable::AlterTableOperation::DROP_FOREIGN_KEY:
300 drop_fkeys.push_back(operation.drop_name());
310 if (not (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
311 create_info->default_table_charset= table->getShare()->table_charset;
316 table->
cursor->info(HA_STATUS_AUTO);
317 create_info->auto_increment_value= table->
cursor->stats.auto_increment_value;
318 if (create_info->auto_increment_value != original_proto.options().auto_increment_value())
319 table_options->set_has_user_set_auto_increment_value(
false);
322 table->restoreRecordAsDefault();
328 for (
Field **f_ptr= table->getFields(); (field= *f_ptr); f_ptr++)
331 vector<string>::iterator it= drop_columns.begin();
332 while (it != drop_columns.end())
334 if (not system_charset_info->strcasecmp(field->
field_name, it->c_str()))
337 if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
338 not (used_fields & HA_CREATE_USED_AUTO))
340 create_info->auto_increment_value= 0;
341 create_info->used_fields|= HA_CREATE_USED_AUTO;
348 if (it != drop_columns.end())
350 drop_columns.erase(it);
360 while ((def= def_it++))
373 new_create_list.push_back(def);
384 new_create_list.push_back(def);
385 AlterInfo::alter_list_t::iterator alter(alter_info->alter_list.begin());
387 for (; alter != alter_info->alter_list.end(); alter++)
389 if (not system_charset_info->strcasecmp(field->
field_name, alter->name))
393 if (alter != alter_info->alter_list.end())
395 def->setDefaultValue(alter->def, NULL);
397 alter_info->alter_list.erase(alter);
404 while ((def= def_it++))
406 if (def->
change && ! def->field)
408 my_error(ER_BAD_FIELD_ERROR, MYF(0), def->
change, table->getMutableShare()->getTableName());
414 if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->
change)
416 alter_info->error_if_not_empty=
true;
420 new_create_list.push_back(def);
422 else if (def->
after == first_keyword)
424 new_create_list.push_front(def);
431 while ((find= find_it++))
439 my_error(ER_BAD_FIELD_ERROR, MYF(0), def->
after, table->getMutableShare()->getTableName());
455 if (alter_table_message.build_method() == message::AlterTable::BUILD_ONLINE)
457 my_error(*session->getQueryString(), ER_NOT_SUPPORTED_YET);
463 if (not alter_info->alter_list.empty())
465 my_error(ER_BAD_FIELD_ERROR, MYF(0), alter_info->alter_list.front().name, table->getMutableShare()->getTableName());
469 if (new_create_list.is_empty())
471 my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), MYF(0));
480 for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++, key_info++)
482 const char *key_name= key_info->name;
484 vector<string>::iterator it= drop_keys.begin();
485 while (it != drop_keys.end())
487 if (not system_charset_info->strcasecmp(key_name, it->c_str()))
492 if (it != drop_keys.end())
500 for (uint32_t j= 0; j < key_info->key_parts; j++, key_part++)
502 if (not key_part->field)
505 const char *key_part_name= key_part->field->
field_name;
508 while ((cfield= field_it++))
512 if (not system_charset_info->strcasecmp(key_part_name, cfield->
change))
515 else if (not system_charset_info->strcasecmp(key_part_name, cfield->
field_name))
522 uint32_t key_part_length= key_part->length;
539 (cfield->field->field_length == key_part_length) ||
541 (cfield->length < key_part_length / key_part->field->charset()->mbmaxlen)))
544 key_part_length/= key_part->field->charset()->mbmaxlen;
547 if (key_parts.size())
550 key_create_info.algorithm= key_info->algorithm;
552 if (key_info->flags & HA_USES_BLOCK_SIZE)
553 key_create_info.block_size= key_info->block_size;
555 if (key_info->flags & HA_USES_COMMENT)
556 key_create_info.comment= key_info->comment;
558 Key::Keytype key_type= key_info->flags & HA_NOSAME
559 ? (is_primary_key(key_name) ? Key::PRIMARY : Key::UNIQUE)
561 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));
566 for (int32_t j= 0; j < original_proto.fk_constraint_size(); j++)
568 vector<string>::iterator it= drop_fkeys.begin();
569 while (it != drop_fkeys.end())
571 if (! system_charset_info->strcasecmp(original_proto.fk_constraint(j).name().c_str(), it->c_str()))
578 if (it != drop_fkeys.end())
580 drop_fkeys.erase(it);
585 *pfkey= original_proto.fk_constraint(j);
591 while ((key= key_it++))
593 if (key->type == Key::FOREIGN_KEY)
595 if (((
Foreign_key *)key)->validate(new_create_list))
601 add_foreign_key_to_table_message(&table_message,
611 if (key->type != Key::FOREIGN_KEY)
612 new_key_list.push_back(key);
614 if (key->name.data() && is_primary_key(key->name.data()))
616 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.data());
623 for (
int j= 0; j < table_message.fk_constraint_size(); j++)
625 if (! table_message.fk_constraint(j).has_name())
627 std::string name(table->getMutableShare()->getTableName());
630 name.append(
"_ibfk_");
631 snprintf(number,
sizeof(number),
"%d", j+1);
635 pfkey->set_name(name);
639 if (drop_keys.size())
641 my_error(ER_CANT_DROP_FIELD_OR_KEY,
643 drop_keys.front().c_str());
647 if (drop_columns.size())
649 my_error(ER_CANT_DROP_FIELD_OR_KEY,
651 drop_columns.front().c_str());
655 if (drop_fkeys.size())
657 my_error(ER_CANT_DROP_FIELD_OR_KEY,
659 drop_fkeys.front().c_str());
663 if (not alter_info->alter_list.empty())
665 my_error(ER_CANT_DROP_FIELD_OR_KEY,
667 alter_info->alter_list.front().name);
671 if (not table_message.options().has_comment()
672 && table->getMutableShare()->hasComment())
674 table_options->set_comment(table->getMutableShare()->getComment());
677 if (table->getShare()->getType())
679 table_message.set_type(message::Table::TEMPORARY);
682 table_message.set_creation_timestamp(table->getShare()->getTableMessage()->creation_timestamp());
683 table_message.set_version(table->getShare()->getTableMessage()->version());
684 table_message.set_uuid(table->getShare()->getTableMessage()->uuid());
686 alter_info->create_list.swap(new_create_list);
687 alter_info->key_list.swap(new_key_list);
689 size_t num_engine_options= table_message.engine().options_size();
690 size_t original_num_engine_options= original_proto.engine().options_size();
691 for (
size_t x= 0; x < original_num_engine_options; ++x)
695 for (
size_t y= 0; y < num_engine_options; ++y)
697 found= not table_message.engine().options(y).name().compare(original_proto.engine().options(x).name());
707 opt->set_name(original_proto.engine().options(x).name());
708 opt->set_state(original_proto.engine().options(x).state());
712 drizzled::message::update(table_message);
718 static int discard_or_import_tablespace(Session *session,
719 TableList *table_list,
726 session->set_proc_info(
"discard_or_import_tablespace");
732 session->setDoingTablespaceOperation(
true);
733 Table* table= session->openTableLock(table_list, TL_WRITE);
736 session->setDoingTablespaceOperation(
false);
742 error= table->cursor->ha_discard_or_import_tablespace(discard);
744 session->set_proc_info(
"end");
751 if (not session->endActiveTransaction())
758 *session->getQueryString(),
764 session->setDoingTablespaceOperation(
false);
772 table->print_error(error, MYF(0));
792 Table *table,
int indexes_were_disabled,
796 if (alter_table_message.has_alter_keys_onoff()
797 && alter_table_message.alter_keys_onoff().enable())
802 if ((! alter_table_message.has_alter_keys_onoff() && indexes_were_disabled)
803 || (alter_table_message.has_alter_keys_onoff()
804 && ! alter_table_message.alter_keys_onoff().enable()))
809 if (error == HA_ERR_WRONG_COMMAND)
811 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
812 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
813 table->getMutableShare()->getTableName());
818 table->print_error(error, MYF(0));
824 static bool lockTableIfDifferent(Session &session,
825 identifier::Table &original_table_identifier,
826 identifier::Table &new_table_identifier,
830 if (not (original_table_identifier == new_table_identifier))
832 if (original_table_identifier.isTmp())
834 if (session.open_tables.find_temporary_table(new_table_identifier))
836 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
842 name_lock= session.lock_table_name_if_not_cached(new_table_identifier);
845 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
852 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
855 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
856 session.unlink_open_table(name_lock);
929 if (not original_table_identifier.isValid())
932 if (not new_table_identifier.isValid())
937 table->use_all_columns();
942 original_engine= table->getMutableShare()->getEngine();
944 if (not create_info->db_type)
946 create_info->db_type= original_engine;
948 new_engine= create_info->db_type;
951 create_proto.set_schema(new_table_identifier.getSchemaName());
952 create_proto.set_type(new_table_identifier.getType());
958 if (new_engine != original_engine &&
962 my_error(ER_ROW_IS_REFERENCED, MYF(0));
967 if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
968 new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
970 my_error(ER_ILLEGAL_HA, new_table_identifier);
983 if ((alter_table_message.has_rename()
984 || alter_table_message.has_alter_keys_onoff())
985 && alter_table_message.operations_size() == 0)
993 tmp.reset(ALTER_RENAME);
994 tmp.reset(ALTER_KEYS_ONOFF);
995 tmp&= alter_info->flags;
997 if((not (tmp.any()) && not table->getShare()->getType()))
999 if (alter_table_message.has_alter_keys_onoff())
1001 error= apply_online_alter_keys_onoff(session, table,
1002 alter_table_message.alter_keys_onoff());
1004 if (error == HA_ERR_WRONG_COMMAND)
1007 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1008 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1013 if (alter_table_message.has_rename())
1015 error= apply_online_rename_table(session,
1018 original_table_identifier,
1019 new_table_identifier,
1020 alter_table_message.rename());
1022 if (error == HA_ERR_WRONG_COMMAND)
1025 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1026 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1033 TransactionServices::allocateNewTransactionId();
1035 *session->getQueryString(),
1036 *session->schema());
1039 else if (error > EE_OK)
1041 table->print_error(error, MYF(0));
1044 table_list->
table= NULL;
1050 if (alter_table_message.build_method() == message::AlterTable::BUILD_ONLINE)
1052 my_error(*session->getQueryString(), ER_NOT_SUPPORTED_YET);
1057 new_engine= create_info->db_type;
1059 if (
prepare_alter_table(session, table, create_info, original_proto, create_proto, alter_table_message, alter_info))
1064 set_table_default_charset(session->catalog().identifier(), create_info, new_table_identifier.getSchemaName().c_str());
1066 snprintf(tmp_name,
sizeof(tmp_name),
"%s-%lx_%"PRIx64,
TMP_FILE_PREFIX, (
unsigned long) current_pid, session->thread_id);
1075 original_table_identifier.getSchemaName(),
1077 create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1078 message::Table::TEMPORARY);
1084 create_proto.set_name(new_table_as_temporary.getTableName());
1085 create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1087 error= create_table(session,
1088 new_table_as_temporary,
1089 create_info, create_proto, alter_info,
true, 0,
false);
1097 Table *new_table= open_alter_table(session, table, new_table_as_temporary);
1102 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1109 session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1115 new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1116 new_table->next_number_field= new_table->found_next_number_field;
1117 error= copy_data_between_tables(session,
1120 alter_info->create_list,
1126 alter_table_message,
1127 alter_info->error_if_not_empty);
1130 assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
1141 if (alter_info->error_if_not_empty && session->
row_count)
1143 my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1146 if (original_table_identifier.isTmp())
1151 session->open_tables.close_temporary_table(new_table);
1155 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1168 new_table->intern_close_table();
1169 if (new_table->hasShare())
1171 delete new_table->getMutableShare();
1177 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1179 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1185 else if (original_table_identifier.isTmp())
1188 if (session->open_tables.lock)
1190 session->unlockTables(session->open_tables.lock);
1191 session->open_tables.lock= 0;
1195 session->open_tables.close_temporary_table(table);
1198 new_table->getMutableShare()->setIdentifier(new_table_identifier);
1200 new_table_identifier.setPath(new_table_as_temporary.getPath());
1202 if (rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1216 new_table->intern_close_table();
1218 if (new_table->hasShare())
1220 delete new_table->getMutableShare();
1227 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1246 snprintf(old_name,
sizeof(old_name),
"%s2-%lx-%"PRIx64,
TMP_FILE_PREFIX, (
unsigned long) current_pid, session->thread_id);
1248 files_charset_info->casedn_str(old_name);
1250 wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1265 original_table_identifier.getSchemaName(),
1266 old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1267 message::Table::TEMPORARY);
1269 drizzled::error_t rename_error= EE_OK;
1270 if (rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1272 error= ER_ERROR_ON_RENAME;
1273 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1277 if (rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1280 rename_error= ER_ERROR_ON_RENAME;
1282 plugin::StorageEngine::dropTable(*session, new_table_identifier);
1284 plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1286 rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1290 plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1310 *session->getQueryString(),
1311 *session->schema());
1312 table_list->
table= NULL;
1326 snprintf(tmp_name,
sizeof(tmp_name), ER(ER_INSERT_INFO),
1327 (ulong) (copied + deleted), (ulong) deleted,
1329 session->
my_ok(copied + deleted, 0, 0L, tmp_name);
1333 static int apply_online_alter_keys_onoff(Session *session,
1335 const message::AlterTable::AlterKeysOnOff &op)
1351 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1352 wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1354 error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1361 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1362 wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1364 error= table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1372 static int apply_online_rename_table(Session *session,
1374 plugin::StorageEngine *original_engine,
1375 identifier::Table &original_table_identifier,
1376 identifier::Table &new_table_identifier,
1377 const message::AlterTable::RenameTable &alter_operation)
1381 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1388 if (not (original_table_identifier == new_table_identifier))
1390 assert(alter_operation.to_name() == new_table_identifier.getTableName());
1391 assert(alter_operation.to_schema() == new_table_identifier.getSchemaName());
1393 session->set_proc_info(
"rename");
1398 session->close_cached_table(table);
1409 my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
1414 if (rename_table(*session, original_engine, original_table_identifier, new_table_identifier))
1423 bool alter_table(Session *session,
1424 identifier::Table &original_table_identifier,
1425 identifier::Table &new_table_identifier,
1426 HA_CREATE_INFO *create_info,
1427 const message::Table &original_proto,
1428 message::Table &create_proto,
1429 TableList *table_list,
1430 AlterInfo *alter_info,
1437 message::AlterTable *alter_table_message= session->lex().alter_table();
1439 alter_table_message->set_catalog(original_table_identifier.getCatalogName());
1440 alter_table_message->set_schema(original_table_identifier.getSchemaName());
1441 alter_table_message->set_name(original_table_identifier.getTableName());
1443 if (alter_table_message->operations_size()
1444 && (alter_table_message->operations(0).operation()
1445 == message::AlterTable::AlterTableOperation::DISCARD_TABLESPACE
1446 || alter_table_message->operations(0).operation()
1447 == message::AlterTable::AlterTableOperation::IMPORT_TABLESPACE))
1449 bool discard= (alter_table_message->operations(0).operation() ==
1450 message::AlterTable::AlterTableOperation::DISCARD_TABLESPACE);
1452 return discard_or_import_tablespace(session, table_list, discard);
1455 session->set_proc_info(
"init");
1457 if (not (table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
1460 session->set_proc_info(
"gained write lock on table");
1467 Table *name_lock= NULL;
1469 if (not lockTableIfDifferent(*session, original_table_identifier, new_table_identifier, name_lock))
1476 original_table_identifier,
1477 new_table_identifier,
1481 *alter_table_message,
1490 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1491 session->unlink_open_table(name_lock);
1500 copy_data_between_tables(Session *session,
1501 Table *from, Table *to,
1502 List<CreateField> &create,
1504 uint32_t order_num, Order *order,
1507 message::AlterTable &alter_table_message,
1508 bool error_if_not_empty)
1511 CopyField *copy,*copy_end;
1512 ulong found_count,delete_count;
1514 SortField *sortorder;
1518 List<Item> all_fields;
1519 ha_rows examined_rows;
1520 bool auto_increment_field_copied= 0;
1537 to->getMutableShare()->getEngine()->startStatement(session);
1539 copy=
new CopyField[to->getShare()->sizeFields()];
1541 if (to->cursor->ha_external_lock(session, F_WRLCK))
1546 alter_table_message);
1549 session->setAbortOnWarning(not ignore);
1551 from->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1552 to->cursor->ha_start_bulk_insert(from->cursor->stats.records);
1554 List<CreateField>::iterator it(create.begin());
1556 for (Field **ptr= to->getFields(); *ptr ; ptr++)
1558 CreateField* def=it++;
1561 if (*ptr == to->next_number_field)
1562 auto_increment_field_copied=
true;
1564 (copy_end++)->set(*ptr,def->field,0);
1569 found_count=delete_count=0;
1575 if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1577 char warn_buff[DRIZZLE_ERRMSG_SIZE];
1578 snprintf(warn_buff,
sizeof(warn_buff),
1579 _(
"order_st BY ignored because there is a user-defined clustered "
1580 "index in the table '%-.192s'"),
1581 from->getMutableShare()->getTableName());
1582 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1587 FileSort filesort(*session);
1588 from->sort.io_cache=
new internal::io_cache_st;
1591 tables.setTableName(from->getMutableShare()->getTableName());
1592 tables.alias= tables.getTableName();
1593 tables.setSchemaName(from->getMutableShare()->getSchemaName());
1596 session->lex().select_lex.setup_ref_array(session, order_num);
1597 if (
setup_order(session, session->lex().select_lex.ref_pointer_array, &tables, fields, all_fields, order))
1599 sortorder= make_unireg_sortorder(order, &length, NULL);
1600 if ((from->sort.found_records= filesort.run(from, sortorder, length, (optimizer::SqlSelect *) 0, HA_POS_ERROR, 1, examined_rows)) == HA_POS_ERROR)
1606 to->use_all_columns();
1608 error= info.init_read_record(session, from, NULL, 1,
true);
1611 to->print_error(errno, MYF(0));
1618 to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1621 session->row_count= 0;
1622 to->restoreRecordAsDefault();
1623 while (not (error=info.read_record(&info)))
1625 if (session->getKilled())
1627 session->send_kill_message();
1631 session->row_count++;
1633 if (error_if_not_empty)
1638 if (to->next_number_field)
1640 if (auto_increment_field_copied)
1641 to->auto_increment_field_not_null=
true;
1643 to->next_number_field->reset();
1646 for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1648 if (not copy->to_field->hasDefault() and copy->from_null_ptr and *copy->from_null_ptr & copy->from_bit)
1650 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1651 ER_WARN_DATA_TRUNCATED, 1);
1652 copy->to_field->reset();
1657 copy_ptr->do_copy(copy_ptr);
1665 prev_insert_id= to->cursor->next_insert_id;
1666 error= to->cursor->insertRecord(to->record[0]);
1667 to->auto_increment_field_not_null=
false;
1671 if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1673 to->print_error(error, MYF(0));
1676 to->cursor->restore_auto_increment(prev_insert_id);
1685 info.end_read_record();
1686 from->free_io_cache();
1689 if (to->cursor->ha_end_bulk_insert() && error <= 0)
1691 to->print_error(errno, MYF(0));
1694 to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1703 if (not session->endActiveTransaction())
1708 session->setAbortOnWarning(
false);
1709 from->free_io_cache();
1710 *copied= found_count;
1711 *deleted=delete_count;
1712 to->cursor->ha_release_auto_increment();
1714 if (to->cursor->ha_external_lock(session, F_UNLCK))
1719 return error > 0 ? -1 : 0;
1722 static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier)
1725 if (table->getShare()->getType())
1728 tbl.setSchemaName(identifier.getSchemaName().c_str());
1729 tbl.alias= identifier.getTableName().c_str();
1730 tbl.setTableName(identifier.getTableName().c_str());
1733 return session->openTable(&tbl, NULL, DRIZZLE_LOCK_IGNORE_FLUSH);
1738 return session->open_temporary_table(identifier,
false);