62
56
List<CreateField> &create,
64
58
uint32_t order_num,
68
62
enum enum_enable_or_disable keys_onoff,
69
63
bool error_if_not_empty);
71
static bool prepare_alter_table(Session *session,
65
static bool mysql_prepare_alter_table(Session *session,
73
67
HA_CREATE_INFO *create_info,
74
68
const message::Table &original_proto,
75
69
message::Table &table_message,
76
70
AlterInfo *alter_info);
78
static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier);
82
AlterTable::AlterTable(Session *in_session, Table_ident *ident, drizzled::ha_build_method build_arg) :
83
CreateTable(in_session)
85
in_session->lex->sql_command= SQLCOM_ALTER_TABLE;
87
alter_info.build_method= build_arg;
90
} // namespace statement
72
static int create_temporary_table(Session *session,
73
TableIdentifier &identifier,
74
HA_CREATE_INFO *create_info,
75
message::Table &create_message,
76
AlterInfo *alter_info);
78
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier);
92
80
bool statement::AlterTable::execute()
94
TableList *first_table= (TableList *) getSession()->lex->select_lex.table_list.first;
95
TableList *all_tables= getSession()->lex->query_tables;
82
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
83
TableList *all_tables= session->lex->query_tables;
96
84
assert(first_table == all_tables && first_table != 0);
97
Select_Lex *select_lex= &getSession()->lex->select_lex;
85
Select_Lex *select_lex= &session->lex->select_lex;
98
86
bool need_start_waiting= false;
100
is_engine_set= not createTableMessage().engine().name().empty();
102
88
if (is_engine_set)
104
create_info().db_type=
105
plugin::StorageEngine::findByName(*getSession(), createTableMessage().engine().name());
91
plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
107
if (create_info().db_type == NULL)
93
if (create_info.db_type == NULL)
109
my_error(createTableMessage().engine().name(), ER_UNKNOWN_STORAGE_ENGINE, MYF(0));
95
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
96
create_table_message.engine().name().c_str());
116
103
assert(select_lex->db);
118
105
/* Chicken/Egg... we need to search for the table, to know if the table exists, so we can build a full identifier from it */
119
message::table::shared_ptr original_table_message;
106
message::Table original_table_message;
121
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
122
if (plugin::StorageEngine::getTableDefinition(*getSession(), identifier, original_table_message) != EEXIST)
108
TableIdentifier identifier(first_table->db, first_table->table_name);
109
if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
124
my_error(ER_BAD_TABLE_ERROR, identifier);
111
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
128
if (not create_info().db_type)
115
if (not create_info.db_type)
130
create_info().db_type=
131
plugin::StorageEngine::findByName(*getSession(), original_table_message->engine().name());
118
plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
133
if (not create_info().db_type)
120
if (not create_info.db_type)
135
my_error(ER_BAD_TABLE_ERROR, identifier);
122
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
141
128
if (not validateCreateTableOption())
144
if (getSession()->inTransaction())
146
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
150
if (not (need_start_waiting= not getSession()->wait_if_global_read_lock(0, 1)))
133
/* ALTER TABLE ends previous transaction */
134
if (not session->endActiveTransaction())
139
if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
154
if (original_table_message->type() == message::Table::STANDARD )
145
if (original_table_message.type() == message::Table::STANDARD )
156
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
157
identifier::Table new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
158
getSession()->lex->name.str ? getSession()->lex->name.str : first_table->getTableName());
147
TableIdentifier identifier(first_table->db, first_table->table_name);
148
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
149
session->lex->name.str ? session->lex->name.str : first_table->table_name);
160
res= alter_table(getSession(),
151
res= alter_table(session,
164
*original_table_message,
165
createTableMessage(),
155
original_table_message,
156
create_table_message,
168
159
select_lex->order_list.elements,
169
(Order *) select_lex->order_list.first,
170
getSession()->lex->ignore);
160
(order_st *) select_lex->order_list.first,
161
session->lex->ignore);
174
identifier::Table catch22(first_table->getSchemaName(), first_table->getTableName());
175
Table *table= getSession()->find_temporary_table(catch22);
165
Table *table= session->find_temporary_table(first_table);
178
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
179
identifier::Table new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
180
getSession()->lex->name.str ? getSession()->lex->name.str : first_table->getTableName(),
181
table->getMutableShare()->getPath());
168
TableIdentifier identifier(first_table->db, first_table->table_name, table->getMutableShare()->getPath());
169
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
170
session->lex->name.str ? session->lex->name.str : first_table->table_name,
171
table->getMutableShare()->getPath());
183
res= alter_table(getSession(),
173
res= alter_table(session,
187
*original_table_message,
188
createTableMessage(),
177
original_table_message,
178
create_table_message,
191
181
select_lex->order_list.elements,
192
(Order *) select_lex->order_list.first,
193
getSession()->lex->ignore);
182
(order_st *) select_lex->order_list.first,
183
session->lex->ignore);
346
333
new_create_list.push_back(def);
347
334
alter_it.rewind(); /* Change default if ALTER */
348
335
AlterColumn *alter;
350
336
while ((alter= alter_it++))
352
338
if (! my_strcasecmp(system_charset_info,field->field_name, alter->name))
358
343
if (def->sql_type == DRIZZLE_TYPE_BLOB)
360
345
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
364
348
if ((def->def= alter->def))
366
350
/* Use new default */
367
351
def->flags&= ~NO_DEFAULT_VALUE_FLAG;
371
354
def->flags|= NO_DEFAULT_VALUE_FLAG;
373
355
alter_it.remove();
379
360
while ((def= def_it++)) /* Add new columns */
381
362
if (def->change && ! def->field)
383
364
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
387
If we have been given a field which has no default value, and is not null then we need to bail.
368
Check that the DATE/DATETIME not null field we are going to add is
369
either has a default value or the '0000-00-00' is allowed by the
371
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
372
flag to allow ALTER Table only if the table to be altered is empty.
389
if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->change)
374
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
375
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
376
! alter_info->datetime_field &&
377
! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
379
alter_info->datetime_field= def;
391
380
alter_info->error_if_not_empty= true;
393
382
if (! def->after)
395
383
new_create_list.push_back(def);
397
384
else if (def->after == first_keyword)
399
385
new_create_list.push_front(def);
403
388
CreateField *find;
404
389
find_it.rewind();
406
390
while ((find= find_it++)) /* Add new columns */
408
if (not my_strcasecmp(system_charset_info,def->after, find->field_name))
392
if (! my_strcasecmp(system_charset_info,def->after, find->field_name))
414
397
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
418
400
find_it.after(def); /* Put element after this */
421
402
XXX: hack for Bug#28427.
422
403
If column order has changed, force OFFLINE ALTER Table
723
691
We set this flag so that ha_innobase::open and ::external_lock() do
724
692
not complain when we lock the table
726
session->setDoingTablespaceOperation(true);
727
if (not (table= session->openTableLock(table_list, TL_WRITE)))
694
session->tablespace_op= true;
695
if (!(table= session->openTableLock(table_list, TL_WRITE)))
729
session->setDoingTablespaceOperation(false);
697
session->tablespace_op= false;
735
error= table->cursor->ha_discard_or_import_tablespace(discard);
737
session->set_proc_info("end");
742
/* The ALTER Table is always in its own transaction */
743
error= transaction_services.autocommitOrRollback(*session, false);
744
if (not session->endActiveTransaction())
750
write_bin_log(session, *session->getQueryString());
754
(void) transaction_services.autocommitOrRollback(*session, error);
755
session->setDoingTablespaceOperation(false);
701
error= table->cursor->ha_discard_or_import_tablespace(discard);
703
session->set_proc_info("end");
708
/* The ALTER Table is always in its own transaction */
709
error= transaction_services.autocommitOrRollback(session, false);
710
if (! session->endActiveTransaction())
714
write_bin_log(session, session->query.c_str());
717
(void) transaction_services.autocommitOrRollback(session, error);
718
session->tablespace_op=false;
996
948
while the fact that the table is still open gives us protection
997
949
from concurrent DDL statements.
1000
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* DDL wait for/blocker */
1001
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
951
LOCK_open.lock(); /* DDL wait for/blocker */
952
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1003
954
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1005
955
/* COND_refresh will be signaled in close_thread_tables() */
1010
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* DDL wait for/blocker */
1011
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1013
error= table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
958
LOCK_open.lock(); /* DDL wait for/blocker */
959
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
961
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1015
962
/* COND_refresh will be signaled in close_thread_tables() */
1019
970
if (error == HA_ERR_WRONG_COMMAND)
1022
973
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1023
974
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1024
975
table->getAlias());
1027
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Lock to remove all instances of table from table cache before ALTER */
978
LOCK_open.lock(); /* Lock to remove all instances of table from table cache before ALTER */
1029
980
Unlike to the above case close_cached_table() below will remove ALL
1030
981
instances of Table from table cache (it will also remove table lock
1031
982
held by this thread). So to make actual table renaming and writing
1032
983
to binlog atomic we have to put them into the same critical section
1033
protected by table::Cache::singleton().mutex() mutex. This also removes gap for races between
1034
access() and rename_table() calls.
984
protected by LOCK_open mutex. This also removes gap for races between
985
access() and mysql_rename_table() calls.
1037
if (not error && not (original_table_identifier == new_table_identifier))
988
if (error == 0 && not (original_table_identifier == new_table_identifier))
1039
990
session->set_proc_info("rename");
1256
1225
if (new_table->hasShare())
1258
delete new_table->getMutableShare();
1227
delete new_table->s;
1261
1231
delete new_table;
1265
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* ALTER TABLE */
1267
Data is copied. Now we:
1268
1) Wait until all other threads close old version of table.
1269
2) Close instances of table open by this thread and replace them
1270
with exclusive name-locks.
1271
3) Rename the old table to a temp name, rename the new one to the
1273
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1274
we reopen new version of table.
1275
5) Write statement to the binary log.
1276
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1277
remove name-locks from list of open tables and table cache.
1278
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1279
call to remove name-locks from table cache and list of open table.
1282
session->set_proc_info("rename result table");
1284
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1286
my_casedn_str(files_charset_info, old_name);
1288
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1289
session->close_data_files_and_morph_locks(original_table_identifier);
1294
This leads to the storage engine (SE) not being notified for renames in
1295
rename_table(), because we just juggle with the FRM and nothing
1296
more. If we have an intermediate table, then we notify the SE that
1297
it should become the actual table. Later, we will recycle the old table.
1298
However, in case of ALTER Table RENAME there might be no intermediate
1299
table. This is when the old and new tables are compatible, according to
1300
compare_table(). Then, we need one additional call to
1302
identifier::Table original_table_to_drop(original_table_identifier.getSchemaName(),
1303
old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1304
message::Table::TEMPORARY);
1306
drizzled::error_t rename_error= EE_OK;
1307
if (rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1234
LOCK_open.lock(); /* ALTER TABLE */
1237
Data is copied. Now we:
1238
1) Wait until all other threads close old version of table.
1239
2) Close instances of table open by this thread and replace them
1240
with exclusive name-locks.
1241
3) Rename the old table to a temp name, rename the new one to the
1243
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1244
we reopen new version of table.
1245
5) Write statement to the binary log.
1246
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1247
remove name-locks from list of open tables and table cache.
1248
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1249
call to remove name-locks from table cache and list of open table.
1252
session->set_proc_info("rename result table");
1254
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1256
my_casedn_str(files_charset_info, old_name);
1258
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1259
session->close_data_files_and_morph_locks(original_table_identifier);
1264
This leads to the storage engine (SE) not being notified for renames in
1265
mysql_rename_table(), because we just juggle with the FRM and nothing
1266
more. If we have an intermediate table, then we notify the SE that
1267
it should become the actual table. Later, we will recycle the old table.
1268
However, in case of ALTER Table RENAME there might be no intermediate
1269
table. This is when the old and new tables are compatible, according to
1270
compare_table(). Then, we need one additional call to
1272
TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1273
old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1274
message::Table::TEMPORARY);
1276
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1279
quick_rm_table(*session, new_table_as_temporary);
1283
if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1309
error= ER_ERROR_ON_RENAME;
1310
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1285
/* Try to get everything back. */
1288
quick_rm_table(*session, new_table_identifier);
1290
quick_rm_table(*session, new_table_as_temporary);
1292
mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1314
if (rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1316
/* Try to get everything back. */
1317
rename_error= ER_ERROR_ON_RENAME;
1319
plugin::StorageEngine::dropTable(*session, new_table_identifier);
1321
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1323
rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1327
plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1334
An error happened while we were holding exclusive name-lock on table
1335
being altered. To be safe under LOCK TABLES we should remove placeholders
1336
from list of open tables list and table cache.
1338
session->unlink_open_table(table);
1296
quick_rm_table(*session, original_table_to_drop);
1303
An error happened while we were holding exclusive name-lock on table
1304
being altered. To be safe under LOCK TABLES we should remove placeholders
1305
from list of open tables list and table cache.
1307
session->unlink_open_table(table);
1344
1315
session->set_proc_info("end");
1346
write_bin_log(session, *session->getQueryString());
1317
write_bin_log(session, session->query.c_str());
1347
1318
table_list->table= NULL;
1506
1478
found_count=delete_count=0;
1512
if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1482
if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1484
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1485
snprintf(warn_buff, sizeof(warn_buff),
1486
_("order_st BY ignored because there is a user-defined clustered "
1487
"index in the table '%-.192s'"),
1488
from->getMutableShare()->getTableName());
1489
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1494
from->sort.io_cache= new internal::IO_CACHE;
1496
memset(&tables, 0, sizeof(tables));
1498
tables.alias= tables.table_name= const_cast<char *>(from->getMutableShare()->getTableName());
1499
tables.db= const_cast<char *>(from->getMutableShare()->getSchemaName());
1502
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1503
setup_order(session, session->lex->select_lex.ref_pointer_array,
1504
&tables, fields, all_fields, order) ||
1505
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1506
(from->sort.found_records= filesort(session, from, sortorder, length,
1507
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1508
1, &examined_rows)) ==
1514
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1515
snprintf(warn_buff, sizeof(warn_buff),
1516
_("order_st BY ignored because there is a user-defined clustered "
1517
"index in the table '%-.192s'"),
1518
from->getMutableShare()->getTableName());
1519
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1516
/* Tell handler that we have values for all columns in the to table */
1517
to->use_all_columns();
1518
info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
1520
to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1521
session->row_count= 0;
1522
to->restoreRecordAsDefault(); // Create empty record
1523
while (!(error=info.read_record(&info)))
1525
if (session->killed)
1527
session->send_kill_message();
1531
session->row_count++;
1532
/* Return error if source table isn't empty. */
1533
if (error_if_not_empty)
1538
if (to->next_number_field)
1540
if (auto_increment_field_copied)
1541
to->auto_increment_field_not_null= true;
1524
FileSort filesort(*session);
1525
from->sort.io_cache= new internal::IO_CACHE;
1528
tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1529
tables.alias= const_cast<char *>(tables.getTableName());
1530
tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
1533
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1534
setup_order(session, session->lex->select_lex.ref_pointer_array,
1535
&tables, fields, all_fields, order) ||
1536
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1537
(from->sort.found_records= filesort.run(from, sortorder, length,
1538
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1539
1, examined_rows)) == HA_POS_ERROR)
1546
/* Tell handler that we have values for all columns in the to table */
1547
to->use_all_columns();
1549
error= info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
1543
to->next_number_field->reset();
1546
for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1548
copy_ptr->do_copy(copy_ptr);
1550
prev_insert_id= to->cursor->next_insert_id;
1551
error= to->cursor->insertRecord(to->record[0]);
1552
to->auto_increment_field_not_null= false;
1552
to->print_error(errno, MYF(0));
1559
to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1562
session->row_count= 0;
1563
to->restoreRecordAsDefault(); // Create empty record
1564
while (not (error=info.read_record(&info)))
1566
if (session->getKilled())
1568
session->send_kill_message();
1572
session->row_count++;
1573
/* Return error if source table isn't empty. */
1574
if (error_if_not_empty)
1579
if (to->next_number_field)
1581
if (auto_increment_field_copied)
1582
to->auto_increment_field_not_null= true;
1584
to->next_number_field->reset();
1587
for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1589
if (not copy->to_field->hasDefault() and copy->from_null_ptr and *copy->from_null_ptr & copy->from_bit)
1591
copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1592
ER_WARN_DATA_TRUNCATED, 1);
1593
copy->to_field->reset();
1598
copy_ptr->do_copy(copy_ptr);
1606
prev_insert_id= to->cursor->next_insert_id;
1607
error= to->cursor->insertRecord(to->record[0]);
1608
to->auto_increment_field_not_null= false;
1557
to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1612
if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1614
to->print_error(error, MYF(0));
1617
to->cursor->restore_auto_increment(prev_insert_id);
1559
to->print_error(error, MYF(0));
1562
to->cursor->restore_auto_increment(prev_insert_id);
1626
info.end_read_record();
1627
from->free_io_cache();
1628
delete [] copy; // This is never 0
1630
if (to->cursor->ha_end_bulk_insert() && error <= 0)
1632
to->print_error(errno, MYF(0));
1635
to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1638
Ensure that the new table is saved properly to disk so that we
1641
if (transaction_services.autocommitOrRollback(*session, false))
1644
if (not session->endActiveTransaction())
1649
session->setAbortOnWarning(false);
1571
info.end_read_record();
1572
from->free_io_cache();
1573
delete [] copy; // This is never 0
1575
if (to->cursor->ha_end_bulk_insert() && error <= 0)
1577
to->print_error(errno, MYF(0));
1580
to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1583
Ensure that the new table is saved properly to disk so that we
1586
if (transaction_services.autocommitOrRollback(session, false))
1588
if (! session->endActiveTransaction())
1592
session->abort_on_warning= 0;
1650
1593
from->free_io_cache();
1651
1594
*copied= found_count;
1652
1595
*deleted=delete_count;
1653
1596
to->cursor->ha_release_auto_increment();
1655
if (to->cursor->ha_external_lock(session, F_UNLCK))
1597
if (to->cursor->ha_external_lock(session,F_UNLCK))
1660
1600
return(error > 0 ? -1 : 0);
1663
static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier)
1604
create_temporary_table(Session *session,
1605
TableIdentifier &identifier,
1606
HA_CREATE_INFO *create_info,
1607
message::Table &create_proto,
1608
AlterInfo *alter_info)
1613
Create a table with a temporary name.
1614
We don't log the statement, it will be logged later.
1616
create_proto.set_name(identifier.getTableName());
1618
create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1620
error= mysql_create_table(session,
1622
create_info, create_proto, alter_info, true, 0, false);
1627
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier)
1665
1629
Table *new_table;