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"
45
#include "drizzled/transaction_services.h"
47
#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>
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>
49
53
using namespace std;
64
68
enum enum_enable_or_disable keys_onoff,
65
69
bool error_if_not_empty);
67
static bool mysql_prepare_alter_table(Session *session,
71
static bool prepare_alter_table(Session *session,
69
73
HA_CREATE_INFO *create_info,
70
74
const message::Table &original_proto,
71
75
message::Table &table_message,
72
76
AlterInfo *alter_info);
74
static int create_temporary_table(Session *session,
75
TableIdentifier &identifier,
76
HA_CREATE_INFO *create_info,
77
message::Table &create_message,
78
AlterInfo *alter_info);
80
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier);
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
82
92
bool statement::AlterTable::execute()
84
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
85
TableList *all_tables= session->lex->query_tables;
94
TableList *first_table= (TableList *) getSession()->getLex()->select_lex.table_list.first;
95
TableList *all_tables= getSession()->getLex()->query_tables;
86
96
assert(first_table == all_tables && first_table != 0);
87
Select_Lex *select_lex= &session->lex->select_lex;
97
Select_Lex *select_lex= &getSession()->getLex()->select_lex;
88
98
bool need_start_waiting= false;
100
is_engine_set= not createTableMessage().engine().name().empty();
90
102
if (is_engine_set)
93
plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
104
create_info().db_type=
105
plugin::StorageEngine::findByName(*getSession(), createTableMessage().engine().name());
95
if (create_info.db_type == NULL)
107
if (create_info().db_type == NULL)
97
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
98
create_table_message.engine().name().c_str());
109
my_error(createTableMessage().engine().name(), ER_UNKNOWN_STORAGE_ENGINE, MYF(0));
105
116
assert(select_lex->db);
107
118
/* Chicken/Egg... we need to search for the table, to know if the table exists, so we can build a full identifier from it */
108
message::Table original_table_message;
119
message::table::shared_ptr original_table_message;
110
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
111
if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
121
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
122
if (not (original_table_message= plugin::StorageEngine::getTableMessage(*getSession(), identifier)))
113
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
124
my_error(ER_BAD_TABLE_ERROR, identifier);
117
if (not create_info.db_type)
128
if (not create_info().db_type)
120
plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
130
create_info().db_type=
131
plugin::StorageEngine::findByName(*getSession(), original_table_message->engine().name());
122
if (not create_info.db_type)
133
if (not create_info().db_type)
124
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
135
my_error(ER_BAD_TABLE_ERROR, identifier);
130
141
if (not validateCreateTableOption())
135
/* ALTER TABLE ends previous transaction */
136
if (not session->endActiveTransaction())
141
if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
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)))
147
if (original_table_message.type() == message::Table::STANDARD )
154
if (original_table_message->type() == message::Table::STANDARD )
149
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
150
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
151
session->lex->name.str ? session->lex->name.str : first_table->getTableName());
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());
153
res= alter_table(session,
160
res= alter_table(getSession(),
157
original_table_message,
158
create_table_message,
164
*original_table_message,
165
createTableMessage(),
161
168
select_lex->order_list.elements,
162
169
(Order *) select_lex->order_list.first,
163
session->lex->ignore);
170
getSession()->getLex()->ignore);
167
TableIdentifier catch22(first_table->getSchemaName(), first_table->getTableName());
168
Table *table= session->find_temporary_table(catch22);
174
identifier::Table catch22(first_table->getSchemaName(), first_table->getTableName());
175
Table *table= getSession()->find_temporary_table(catch22);
171
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
172
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
173
session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
174
table->getMutableShare()->getPath());
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());
176
res= alter_table(session,
183
res= alter_table(getSession(),
180
original_table_message,
181
create_table_message,
187
*original_table_message,
188
createTableMessage(),
184
191
select_lex->order_list.elements,
185
192
(Order *) select_lex->order_list.first,
186
session->lex->ignore);
193
getSession()->getLex()->ignore);
236
244
Table instructions
237
245
@retval false success
239
static bool mysql_prepare_alter_table(Session *session,
241
HA_CREATE_INFO *create_info,
242
const message::Table &original_proto,
243
message::Table &table_message,
244
AlterInfo *alter_info)
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)
246
254
/* New column definitions are added here */
247
255
List<CreateField> new_create_list;
248
256
/* New key definitions are added here */
249
257
List<Key> new_key_list;
250
List_iterator<AlterDrop> drop_it(alter_info->drop_list);
251
List_iterator<CreateField> def_it(alter_info->create_list);
252
List_iterator<AlterColumn> alter_it(alter_info->alter_list);
253
List_iterator<Key> key_it(alter_info->key_list);
254
List_iterator<CreateField> find_it(new_create_list);
255
List_iterator<CreateField> field_it(new_create_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());
256
264
List<Key_part_spec> key_parts;
257
265
uint32_t used_fields= create_info->used_fields;
258
266
KeyInfo *key_info= table->key_info;
335
345
def= new CreateField(field, field);
336
346
new_create_list.push_back(def);
337
alter_it.rewind(); /* Change default if ALTER */
347
alter_it= alter_info->alter_list.begin(); /* Change default if ALTER */
338
348
AlterColumn *alter;
339
350
while ((alter= alter_it++))
341
352
if (! my_strcasecmp(system_charset_info,field->field_name, alter->name))
346
358
if (def->sql_type == DRIZZLE_TYPE_BLOB)
348
360
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
351
364
if ((def->def= alter->def))
353
366
/* Use new default */
354
367
def->flags&= ~NO_DEFAULT_VALUE_FLAG;
357
371
def->flags|= NO_DEFAULT_VALUE_FLAG;
358
373
alter_it.remove();
378
def_it= alter_info->create_list.begin();
363
379
while ((def= def_it++)) /* Add new columns */
365
381
if (def->change && ! def->field)
367
383
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
371
Check that the DATE/DATETIME not null field we are going to add is
372
either has a default value or the '0000-00-00' is allowed by the
374
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
375
flag to allow ALTER Table only if the table to be altered is empty.
387
If we have been given a field which has no default value, and is not null then we need to bail.
377
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
378
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
379
! alter_info->datetime_field &&
380
! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
389
if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->change)
382
alter_info->datetime_field= def;
383
391
alter_info->error_if_not_empty= true;
385
393
if (! def->after)
386
395
new_create_list.push_back(def);
387
397
else if (def->after == first_keyword)
388
399
new_create_list.push_front(def);
391
403
CreateField *find;
404
find_it= new_create_list.begin();
393
406
while ((find= find_it++)) /* Add new columns */
395
if (! my_strcasecmp(system_charset_info,def->after, find->field_name))
408
if (not my_strcasecmp(system_charset_info,def->after, find->field_name))
400
414
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
403
418
find_it.after(def); /* Put element after this */
405
421
XXX: hack for Bug#28427.
406
422
If column order has changed, force OFFLINE ALTER Table
696
723
We set this flag so that ha_innobase::open and ::external_lock() do
697
724
not complain when we lock the table
699
session->tablespace_op= true;
700
if (!(table= session->openTableLock(table_list, TL_WRITE)))
726
session->setDoingTablespaceOperation(true);
727
if (not (table= session->openTableLock(table_list, TL_WRITE)))
702
session->tablespace_op= false;
729
session->setDoingTablespaceOperation(false);
706
error= table->cursor->ha_discard_or_import_tablespace(discard);
708
session->set_proc_info("end");
713
/* The ALTER Table is always in its own transaction */
714
error= transaction_services.autocommitOrRollback(session, false);
715
if (! session->endActiveTransaction())
719
write_bin_log(session, session->query.c_str());
722
(void) transaction_services.autocommitOrRollback(session, error);
723
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);
953
996
while the fact that the table is still open gives us protection
954
997
from concurrent DDL statements.
956
LOCK_open.lock(); /* DDL wait for/blocker */
957
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
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);
959
1003
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
960
1005
/* COND_refresh will be signaled in close_thread_tables() */
963
LOCK_open.lock(); /* DDL wait for/blocker */
964
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
966
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
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);
967
1015
/* COND_refresh will be signaled in close_thread_tables() */
975
1019
if (error == HA_ERR_WRONG_COMMAND)
978
1022
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
979
1023
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
980
1024
table->getAlias());
983
LOCK_open.lock(); /* Lock to remove all instances of table from table cache before ALTER */
1027
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Lock to remove all instances of table from table cache before ALTER */
985
1029
Unlike to the above case close_cached_table() below will remove ALL
986
1030
instances of Table from table cache (it will also remove table lock
987
1031
held by this thread). So to make actual table renaming and writing
988
1032
to binlog atomic we have to put them into the same critical section
989
protected by LOCK_open mutex. This also removes gap for races between
990
access() and mysql_rename_table() calls.
1033
protected by table::Cache::singleton().mutex() mutex. This also removes gap for races between
1034
access() and rename_table() calls.
993
if (error == 0 && not (original_table_identifier == new_table_identifier))
1037
if (not error && not (original_table_identifier == new_table_identifier))
995
1039
session->set_proc_info("rename");
1234
1261
delete new_table;
1237
LOCK_open.lock(); /* ALTER TABLE */
1240
Data is copied. Now we:
1241
1) Wait until all other threads close old version of table.
1242
2) Close instances of table open by this thread and replace them
1243
with exclusive name-locks.
1244
3) Rename the old table to a temp name, rename the new one to the
1246
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1247
we reopen new version of table.
1248
5) Write statement to the binary log.
1249
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1250
remove name-locks from list of open tables and table cache.
1251
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1252
call to remove name-locks from table cache and list of open table.
1255
session->set_proc_info("rename result table");
1257
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1259
my_casedn_str(files_charset_info, old_name);
1261
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1262
session->close_data_files_and_morph_locks(original_table_identifier);
1267
This leads to the storage engine (SE) not being notified for renames in
1268
mysql_rename_table(), because we just juggle with the FRM and nothing
1269
more. If we have an intermediate table, then we notify the SE that
1270
it should become the actual table. Later, we will recycle the old table.
1271
However, in case of ALTER Table RENAME there might be no intermediate
1272
table. This is when the old and new tables are compatible, according to
1273
compare_table(). Then, we need one additional call to
1275
TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1276
old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1277
message::Table::TEMPORARY);
1279
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1282
quick_rm_table(*session, new_table_as_temporary);
1286
if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
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))
1288
/* Try to get everything back. */
1291
quick_rm_table(*session, new_table_identifier);
1293
quick_rm_table(*session, new_table_as_temporary);
1295
mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1309
error= ER_ERROR_ON_RENAME;
1310
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1299
quick_rm_table(*session, original_table_to_drop);
1306
An error happened while we were holding exclusive name-lock on table
1307
being altered. To be safe under LOCK TABLES we should remove placeholders
1308
from list of open tables list and table cache.
1310
session->unlink_open_table(table);
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);
1318
1344
session->set_proc_info("end");
1320
write_bin_log(session, session->query.c_str());
1346
write_bin_log(session, *session->getQueryString());
1321
1347
table_list->table= NULL;
1481
1506
found_count=delete_count=0;
1485
if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1487
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1488
snprintf(warn_buff, sizeof(warn_buff),
1489
_("order_st BY ignored because there is a user-defined clustered "
1490
"index in the table '%-.192s'"),
1491
from->getMutableShare()->getTableName());
1492
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1497
from->sort.io_cache= new internal::IO_CACHE;
1499
memset(&tables, 0, sizeof(tables));
1501
tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1502
tables.alias= const_cast<char *>(tables.getTableName());
1503
tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
1506
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1507
setup_order(session, session->lex->select_lex.ref_pointer_array,
1508
&tables, fields, all_fields, order) ||
1509
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1510
(from->sort.found_records= filesort(session, from, sortorder, length,
1511
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1512
1, &examined_rows)) ==
1512
if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
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,
1520
/* Tell handler that we have values for all columns in the to table */
1521
to->use_all_columns();
1522
info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
1524
to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1525
session->row_count= 0;
1526
to->restoreRecordAsDefault(); // Create empty record
1527
while (!(error=info.read_record(&info)))
1529
if (session->killed)
1531
session->send_kill_message();
1535
session->row_count++;
1536
/* Return error if source table isn't empty. */
1537
if (error_if_not_empty)
1542
if (to->next_number_field)
1544
if (auto_increment_field_copied)
1545
to->auto_increment_field_not_null= true;
1547
to->next_number_field->reset();
1550
for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1552
copy_ptr->do_copy(copy_ptr);
1554
prev_insert_id= to->cursor->next_insert_id;
1555
error= to->cursor->insertRecord(to->record[0]);
1556
to->auto_increment_field_not_null= false;
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);
1561
to->cursor->is_fatal_error(error, HA_CHECK_DUP))
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;
1563
to->print_error(error, MYF(0));
1566
to->cursor->restore_auto_increment(prev_insert_id);
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);
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));
1575
info.end_read_record();
1576
from->free_io_cache();
1577
delete [] copy; // This is never 0
1579
if (to->cursor->ha_end_bulk_insert() && error <= 0)
1581
to->print_error(errno, MYF(0));
1584
to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1587
Ensure that the new table is saved properly to disk so that we
1590
if (transaction_services.autocommitOrRollback(session, false))
1592
if (! session->endActiveTransaction())
1596
session->abort_on_warning= 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);
1597
1650
from->free_io_cache();
1598
1651
*copied= found_count;
1599
1652
*deleted=delete_count;
1600
1653
to->cursor->ha_release_auto_increment();
1601
if (to->cursor->ha_external_lock(session,F_UNLCK))
1655
if (to->cursor->ha_external_lock(session, F_UNLCK))
1604
1660
return(error > 0 ? -1 : 0);
1608
create_temporary_table(Session *session,
1609
TableIdentifier &identifier,
1610
HA_CREATE_INFO *create_info,
1611
message::Table &create_proto,
1612
AlterInfo *alter_info)
1617
Create a table with a temporary name.
1618
We don't log the statement, it will be logged later.
1620
create_proto.set_name(identifier.getTableName());
1622
create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1624
error= mysql_create_table(session,
1626
create_info, create_proto, alter_info, true, 0, false);
1631
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier)
1663
static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier)
1633
1665
Table *new_table;