18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
#include <drizzled/show.h>
28
#include <drizzled/lock.h>
29
#include <drizzled/session.h>
30
#include <drizzled/statement/alter_table.h>
31
#include <drizzled/global_charset_info.h>
34
#include <drizzled/gettext.h>
35
#include <drizzled/data_home.h>
36
#include <drizzled/sql_table.h>
37
#include <drizzled/table_proto.h>
38
#include <drizzled/optimizer/range.h>
39
#include <drizzled/time_functions.h>
40
#include <drizzled/records.h>
41
#include <drizzled/pthread_globals.h>
42
#include <drizzled/internal/my_sys.h>
43
#include <drizzled/internal/iocache.h>
44
#include <drizzled/plugin/storage_engine.h>
45
#include <drizzled/copy_field.h>
47
#include <drizzled/transaction_services.h>
49
#include <drizzled/filesort.h>
51
#include <drizzled/message.h>
27
#include "drizzled/show.h"
28
#include "drizzled/lock.h"
29
#include "drizzled/session.h"
30
#include "drizzled/statement/alter_table.h"
31
#include "drizzled/global_charset_info.h"
34
#include "drizzled/gettext.h"
35
#include "drizzled/data_home.h"
36
#include "drizzled/sql_table.h"
37
#include "drizzled/table_proto.h"
38
#include "drizzled/optimizer/range.h"
39
#include "drizzled/time_functions.h"
40
#include "drizzled/records.h"
41
#include "drizzled/pthread_globals.h"
42
#include "drizzled/internal/my_sys.h"
43
#include "drizzled/internal/iocache.h"
45
#include "drizzled/transaction_services.h"
47
#include "drizzled/filesort.h"
49
#include "drizzled/message.h"
53
51
using namespace std;
68
66
enum enum_enable_or_disable keys_onoff,
69
67
bool error_if_not_empty);
71
static bool prepare_alter_table(Session *session,
69
static bool mysql_prepare_alter_table(Session *session,
73
71
HA_CREATE_INFO *create_info,
74
72
const message::Table &original_proto,
75
73
message::Table &table_message,
76
74
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->getLex()->sql_command= SQLCOM_ALTER_TABLE;
87
alter_info.build_method= build_arg;
90
} // namespace statement
76
static int create_temporary_table(Session *session,
77
TableIdentifier &identifier,
78
HA_CREATE_INFO *create_info,
79
message::Table &create_message,
80
AlterInfo *alter_info);
82
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier);
92
84
bool statement::AlterTable::execute()
94
TableList *first_table= (TableList *) getSession()->getLex()->select_lex.table_list.first;
95
TableList *all_tables= getSession()->getLex()->query_tables;
86
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
87
TableList *all_tables= session->lex->query_tables;
96
88
assert(first_table == all_tables && first_table != 0);
97
Select_Lex *select_lex= &getSession()->getLex()->select_lex;
89
Select_Lex *select_lex= &session->lex->select_lex;
98
90
bool need_start_waiting= false;
100
is_engine_set= not createTableMessage().engine().name().empty();
102
92
if (is_engine_set)
104
create_info().db_type=
105
plugin::StorageEngine::findByName(*getSession(), createTableMessage().engine().name());
95
plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
107
if (create_info().db_type == NULL)
97
if (create_info.db_type == NULL)
109
my_error(createTableMessage().engine().name(), ER_UNKNOWN_STORAGE_ENGINE, MYF(0));
99
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
100
create_table_message.engine().name().c_str());
118
109
/* 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
110
message::table::shared_ptr original_table_message;
121
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
122
if (not (original_table_message= plugin::StorageEngine::getTableMessage(*getSession(), identifier)))
112
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
113
if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
124
my_error(ER_BAD_TABLE_ERROR, identifier);
115
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
128
if (not create_info().db_type)
119
if (not create_info.db_type)
130
create_info().db_type=
131
plugin::StorageEngine::findByName(*getSession(), original_table_message->engine().name());
122
plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
133
if (not create_info().db_type)
124
if (not create_info.db_type)
135
my_error(ER_BAD_TABLE_ERROR, identifier);
126
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
141
132
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)))
137
/* ALTER TABLE ends previous transaction */
138
if (not session->endActiveTransaction())
143
if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
154
149
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()->getLex()->name.str ? getSession()->getLex()->name.str : first_table->getTableName());
151
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
152
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
153
session->lex->name.str ? session->lex->name.str : first_table->getTableName());
160
res= alter_table(getSession(),
155
res= alter_table(session,
164
159
*original_table_message,
165
createTableMessage(),
160
create_table_message,
168
163
select_lex->order_list.elements,
169
164
(Order *) select_lex->order_list.first,
170
getSession()->getLex()->ignore);
165
session->lex->ignore);
174
identifier::Table catch22(first_table->getSchemaName(), first_table->getTableName());
175
Table *table= getSession()->find_temporary_table(catch22);
169
TableIdentifier catch22(first_table->getSchemaName(), first_table->getTableName());
170
Table *table= session->find_temporary_table(catch22);
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()->getLex()->name.str ? getSession()->getLex()->name.str : first_table->getTableName(),
181
table->getMutableShare()->getPath());
173
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
174
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
175
session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
176
table->getMutableShare()->getPath());
183
res= alter_table(getSession(),
178
res= alter_table(session,
187
182
*original_table_message,
188
createTableMessage(),
183
create_table_message,
191
186
select_lex->order_list.elements,
192
187
(Order *) select_lex->order_list.first,
193
getSession()->getLex()->ignore);
188
session->lex->ignore);
244
239
Table instructions
245
240
@retval false success
247
static bool prepare_alter_table(Session *session,
249
HA_CREATE_INFO *create_info,
250
const message::Table &original_proto,
251
message::Table &table_message,
252
AlterInfo *alter_info)
242
static bool mysql_prepare_alter_table(Session *session,
244
HA_CREATE_INFO *create_info,
245
const message::Table &original_proto,
246
message::Table &table_message,
247
AlterInfo *alter_info)
254
249
/* New column definitions are added here */
255
250
List<CreateField> new_create_list;
256
251
/* New key definitions are added here */
257
252
List<Key> new_key_list;
258
List<AlterDrop>::iterator drop_it(alter_info->drop_list.begin());
259
List<CreateField>::iterator def_it(alter_info->create_list.begin());
260
List<AlterColumn>::iterator alter_it(alter_info->alter_list.begin());
261
List<Key>::iterator key_it(alter_info->key_list.begin());
262
List<CreateField>::iterator find_it(new_create_list.begin());
263
List<CreateField>::iterator field_it(new_create_list.begin());
253
List_iterator<AlterDrop> drop_it(alter_info->drop_list);
254
List_iterator<CreateField> def_it(alter_info->create_list);
255
List_iterator<AlterColumn> alter_it(alter_info->alter_list);
256
List_iterator<Key> key_it(alter_info->key_list);
257
List_iterator<CreateField> find_it(new_create_list);
258
List_iterator<CreateField> field_it(new_create_list);
264
259
List<Key_part_spec> key_parts;
265
260
uint32_t used_fields= create_info->used_fields;
266
261
KeyInfo *key_info= table->key_info;
345
338
def= new CreateField(field, field);
346
339
new_create_list.push_back(def);
347
alter_it= alter_info->alter_list.begin(); /* Change default if ALTER */
340
alter_it.rewind(); /* Change default if ALTER */
348
341
AlterColumn *alter;
350
342
while ((alter= alter_it++))
352
344
if (! my_strcasecmp(system_charset_info,field->field_name, alter->name))
358
349
if (def->sql_type == DRIZZLE_TYPE_BLOB)
360
351
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
364
354
if ((def->def= alter->def))
366
356
/* Use new default */
367
357
def->flags&= ~NO_DEFAULT_VALUE_FLAG;
371
360
def->flags|= NO_DEFAULT_VALUE_FLAG;
373
361
alter_it.remove();
378
def_it= alter_info->create_list.begin();
379
366
while ((def= def_it++)) /* Add new columns */
381
368
if (def->change && ! def->field)
383
370
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.
374
Check that the DATE/DATETIME not null field we are going to add is
375
either has a default value or the '0000-00-00' is allowed by the
377
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
378
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)
380
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
381
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
382
! alter_info->datetime_field &&
383
! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
385
alter_info->datetime_field= def;
391
386
alter_info->error_if_not_empty= true;
393
388
if (! def->after)
395
389
new_create_list.push_back(def);
397
390
else if (def->after == first_keyword)
399
391
new_create_list.push_front(def);
403
394
CreateField *find;
404
find_it= new_create_list.begin();
406
396
while ((find= find_it++)) /* Add new columns */
408
if (not my_strcasecmp(system_charset_info,def->after, find->field_name))
398
if (! my_strcasecmp(system_charset_info,def->after, find->field_name))
414
403
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
418
406
find_it.after(def); /* Put element after this */
421
408
XXX: hack for Bug#28427.
422
409
If column order has changed, force OFFLINE ALTER Table
723
699
We set this flag so that ha_innobase::open and ::external_lock() do
724
700
not complain when we lock the table
726
session->setDoingTablespaceOperation(true);
727
if (not (table= session->openTableLock(table_list, TL_WRITE)))
702
session->tablespace_op= true;
703
if (!(table= session->openTableLock(table_list, TL_WRITE)))
729
session->setDoingTablespaceOperation(false);
705
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);
709
error= table->cursor->ha_discard_or_import_tablespace(discard);
711
session->set_proc_info("end");
716
/* The ALTER Table is always in its own transaction */
717
error= transaction_services.autocommitOrRollback(session, false);
718
if (not session->endActiveTransaction())
724
write_bin_log(session, *session->getQueryString());
727
(void) transaction_services.autocommitOrRollback(session, error);
728
session->tablespace_op=false;
996
958
while the fact that the table is still open gives us protection
997
959
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);
961
LOCK_open.lock(); /* DDL wait for/blocker */
962
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1003
964
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1005
965
/* 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);
968
LOCK_open.lock(); /* DDL wait for/blocker */
969
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
971
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1015
972
/* COND_refresh will be signaled in close_thread_tables() */
1019
980
if (error == HA_ERR_WRONG_COMMAND)
1022
983
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1023
984
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1024
985
table->getAlias());
1027
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Lock to remove all instances of table from table cache before ALTER */
988
LOCK_open.lock(); /* Lock to remove all instances of table from table cache before ALTER */
1029
990
Unlike to the above case close_cached_table() below will remove ALL
1030
991
instances of Table from table cache (it will also remove table lock
1031
992
held by this thread). So to make actual table renaming and writing
1032
993
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.
994
protected by LOCK_open mutex. This also removes gap for races between
995
access() and mysql_rename_table() calls.
1037
if (not error && not (original_table_identifier == new_table_identifier))
998
if (error == 0 && not (original_table_identifier == new_table_identifier))
1039
1000
session->set_proc_info("rename");
1261
1241
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))
1244
LOCK_open.lock(); /* ALTER TABLE */
1247
Data is copied. Now we:
1248
1) Wait until all other threads close old version of table.
1249
2) Close instances of table open by this thread and replace them
1250
with exclusive name-locks.
1251
3) Rename the old table to a temp name, rename the new one to the
1253
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1254
we reopen new version of table.
1255
5) Write statement to the binary log.
1256
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1257
remove name-locks from list of open tables and table cache.
1258
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1259
call to remove name-locks from table cache and list of open table.
1262
session->set_proc_info("rename result table");
1264
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1266
my_casedn_str(files_charset_info, old_name);
1268
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1269
session->close_data_files_and_morph_locks(original_table_identifier);
1274
This leads to the storage engine (SE) not being notified for renames in
1275
mysql_rename_table(), because we just juggle with the FRM and nothing
1276
more. If we have an intermediate table, then we notify the SE that
1277
it should become the actual table. Later, we will recycle the old table.
1278
However, in case of ALTER Table RENAME there might be no intermediate
1279
table. This is when the old and new tables are compatible, according to
1280
compare_table(). Then, we need one additional call to
1282
TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1283
old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1284
message::Table::TEMPORARY);
1286
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1289
quick_rm_table(*session, new_table_as_temporary);
1293
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);
1295
/* Try to get everything back. */
1298
quick_rm_table(*session, new_table_identifier);
1300
quick_rm_table(*session, new_table_as_temporary);
1302
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);
1306
quick_rm_table(*session, original_table_to_drop);
1313
An error happened while we were holding exclusive name-lock on table
1314
being altered. To be safe under LOCK TABLES we should remove placeholders
1315
from list of open tables list and table cache.
1317
session->unlink_open_table(table);
1344
1325
session->set_proc_info("end");
1506
1488
found_count=delete_count=0;
1512
if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1492
if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1494
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1495
snprintf(warn_buff, sizeof(warn_buff),
1496
_("order_st BY ignored because there is a user-defined clustered "
1497
"index in the table '%-.192s'"),
1498
from->getMutableShare()->getTableName());
1499
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1504
FileSort filesort(*session);
1505
from->sort.io_cache= new internal::IO_CACHE;
1507
memset(&tables, 0, sizeof(tables));
1509
tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1510
tables.alias= const_cast<char *>(tables.getTableName());
1511
tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
1514
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1515
setup_order(session, session->lex->select_lex.ref_pointer_array,
1516
&tables, fields, all_fields, order) ||
1517
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1518
(from->sort.found_records= filesort.run(from, sortorder, length,
1519
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1520
1, examined_rows)) == HA_POS_ERROR)
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,
1527
/* Tell handler that we have values for all columns in the to table */
1528
to->use_all_columns();
1529
info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
1531
to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1532
session->row_count= 0;
1533
to->restoreRecordAsDefault(); // Create empty record
1534
while (!(error=info.read_record(&info)))
1536
if (session->getKilled())
1538
session->send_kill_message();
1542
session->row_count++;
1543
/* Return error if source table isn't empty. */
1544
if (error_if_not_empty)
1549
if (to->next_number_field)
1551
if (auto_increment_field_copied)
1552
to->auto_increment_field_not_null= true;
1524
FileSort filesort(*session);
1525
from->sort.io_cache= new internal::IO_CACHE;
1528
tables.setTableName(from->getMutableShare()->getTableName());
1529
tables.alias= tables.getTableName();
1530
tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
1533
if (session->getLex()->select_lex.setup_ref_array(session, order_num) ||
1534
setup_order(session, session->getLex()->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);
1554
to->next_number_field->reset();
1557
for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1559
copy_ptr->do_copy(copy_ptr);
1561
prev_insert_id= to->cursor->next_insert_id;
1562
error= to->cursor->insertRecord(to->record[0]);
1563
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;
1568
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);
1570
to->print_error(error, MYF(0));
1573
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);
1582
info.end_read_record();
1583
from->free_io_cache();
1584
delete [] copy; // This is never 0
1586
if (to->cursor->ha_end_bulk_insert() && error <= 0)
1588
to->print_error(errno, MYF(0));
1591
to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1594
Ensure that the new table is saved properly to disk so that we
1597
if (transaction_services.autocommitOrRollback(session, false))
1599
if (! session->endActiveTransaction())
1603
session->abort_on_warning= 0;
1650
1604
from->free_io_cache();
1651
1605
*copied= found_count;
1652
1606
*deleted=delete_count;
1653
1607
to->cursor->ha_release_auto_increment();
1655
if (to->cursor->ha_external_lock(session, F_UNLCK))
1608
if (to->cursor->ha_external_lock(session,F_UNLCK))
1660
1611
return(error > 0 ? -1 : 0);
1663
static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier)
1615
create_temporary_table(Session *session,
1616
TableIdentifier &identifier,
1617
HA_CREATE_INFO *create_info,
1618
message::Table &create_proto,
1619
AlterInfo *alter_info)
1624
Create a table with a temporary name.
1625
We don't log the statement, it will be logged later.
1627
create_proto.set_name(identifier.getTableName());
1629
create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1631
error= mysql_create_table(session,
1633
create_info, create_proto, alter_info, true, 0, false);
1638
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier)
1665
1640
Table *new_table;