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;
78
76
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
92
78
bool statement::AlterTable::execute()
94
TableList *first_table= (TableList *) getSession()->getLex()->select_lex.table_list.first;
95
TableList *all_tables= getSession()->getLex()->query_tables;
80
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
81
TableList *all_tables= session->lex->query_tables;
96
82
assert(first_table == all_tables && first_table != 0);
97
Select_Lex *select_lex= &getSession()->getLex()->select_lex;
83
Select_Lex *select_lex= &session->lex->select_lex;
98
84
bool need_start_waiting= false;
100
86
is_engine_set= not createTableMessage().engine().name().empty();
102
88
if (is_engine_set)
104
90
create_info().db_type=
105
plugin::StorageEngine::findByName(*getSession(), createTableMessage().engine().name());
91
plugin::StorageEngine::findByName(*session, createTableMessage().engine().name());
107
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
createTableMessage().engine().name().c_str());
119
106
message::table::shared_ptr original_table_message;
121
108
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
122
if (not (original_table_message= plugin::StorageEngine::getTableMessage(*getSession(), identifier)))
109
if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
124
my_error(ER_BAD_TABLE_ERROR, identifier);
112
identifier.getSQLPath(path);
113
my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
128
117
if (not create_info().db_type)
130
119
create_info().db_type=
131
plugin::StorageEngine::findByName(*getSession(), original_table_message->engine().name());
120
plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
133
122
if (not create_info().db_type)
135
my_error(ER_BAD_TABLE_ERROR, identifier);
125
identifier.getSQLPath(path);
126
my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
141
132
if (not validateCreateTableOption())
144
if (getSession()->inTransaction())
146
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
135
/* ALTER TABLE ends previous transaction */
136
if (not session->endActiveTransaction())
150
if (not (need_start_waiting= not getSession()->wait_if_global_read_lock(0, 1)))
139
if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
156
145
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName());
157
146
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());
147
session->lex->name.str ? session->lex->name.str : first_table->getTableName());
160
res= alter_table(getSession(),
149
res= alter_table(session,
168
157
select_lex->order_list.elements,
169
158
(Order *) select_lex->order_list.first,
170
getSession()->getLex()->ignore);
159
session->lex->ignore);
174
163
identifier::Table catch22(first_table->getSchemaName(), first_table->getTableName());
175
Table *table= getSession()->find_temporary_table(catch22);
164
Table *table= session->find_temporary_table(catch22);
178
167
identifier::Table identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
179
168
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());
169
session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
170
table->getMutableShare()->getPath());
183
res= alter_table(getSession(),
172
res= alter_table(session,
245
234
@retval false success
247
236
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)
238
HA_CREATE_INFO *create_info,
239
const message::Table &original_proto,
240
message::Table &table_message,
241
AlterInfo *alter_info)
254
243
/* New column definitions are added here */
255
244
List<CreateField> new_create_list;
256
245
/* New key definitions are added here */
257
246
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());
247
List_iterator<AlterDrop> drop_it(alter_info->drop_list);
248
List_iterator<CreateField> def_it(alter_info->create_list);
249
List_iterator<AlterColumn> alter_it(alter_info->alter_list);
250
List_iterator<Key> key_it(alter_info->key_list);
251
List_iterator<CreateField> find_it(new_create_list);
252
List_iterator<CreateField> field_it(new_create_list);
264
253
List<Key_part_spec> key_parts;
265
254
uint32_t used_fields= create_info->used_fields;
266
255
KeyInfo *key_info= table->key_info;
345
334
def= new CreateField(field, field);
346
335
new_create_list.push_back(def);
347
alter_it= alter_info->alter_list.begin(); /* Change default if ALTER */
336
alter_it.rewind(); /* Change default if ALTER */
348
337
AlterColumn *alter;
350
339
while ((alter= alter_it++))
531
520
if (key_parts.elements)
533
key_create_information_st key_create_info= default_key_create_info;
522
key_create_information_st key_create_info;
535
Key::Keytype key_type;
524
enum Key::Keytype key_type;
525
memset(&key_create_info, 0, sizeof(key_create_info));
537
527
key_create_info.algorithm= key_info->algorithm;
539
528
if (key_info->flags & HA_USES_BLOCK_SIZE)
540
529
key_create_info.block_size= key_info->block_size;
542
530
if (key_info->flags & HA_USES_COMMENT)
543
531
key_create_info.comment= key_info->comment;
666
652
table_message.set_type(message::Table::TEMPORARY);
669
table_message.set_creation_timestamp(table->getShare()->getTableMessage()->creation_timestamp());
670
table_message.set_version(table->getShare()->getTableMessage()->version());
671
table_message.set_uuid(table->getShare()->getTableMessage()->uuid());
655
table_message.set_creation_timestamp(table->getShare()->getTableProto()->creation_timestamp());
656
table_message.set_version(table->getShare()->getTableProto()->version());
657
table_message.set_uuid(table->getShare()->getTableProto()->uuid());
674
660
alter_info->create_list.swap(new_create_list);
723
709
We set this flag so that ha_innobase::open and ::external_lock() do
724
710
not complain when we lock the table
726
session->setDoingTablespaceOperation(true);
712
session->tablespace_op= true;
727
713
if (not (table= session->openTableLock(table_list, TL_WRITE)))
729
session->setDoingTablespaceOperation(false);
715
session->tablespace_op= false;
742
728
/* The ALTER Table is always in its own transaction */
743
error= transaction_services.autocommitOrRollback(*session, false);
729
error= transaction_services.autocommitOrRollback(session, false);
744
730
if (not session->endActiveTransaction())
754
(void) transaction_services.autocommitOrRollback(*session, error);
755
session->setDoingTablespaceOperation(false);
740
(void) transaction_services.autocommitOrRollback(session, error);
741
session->tablespace_op=false;
825
811
if (session.find_temporary_table(new_table_identifier))
827
my_error(ER_TABLE_EXISTS_ERROR, new_table_identifier);
814
new_table_identifier.getSQLPath(path);
815
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
961
949
if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
962
950
new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
964
my_error(ER_ILLEGAL_HA, new_table_identifier);
953
new_table_identifier.getSQLPath(path);
954
my_error(ER_ILLEGAL_HA, MYF(0), path.c_str());
1482
1472
alter_table_manage_keys(session, to, from->cursor->indexes_are_disabled(), keys_onoff);
1484
1474
/* We can abort alter table for any table type */
1485
session->setAbortOnWarning(not ignore);
1475
session->abort_on_warning= !ignore;
1487
1477
from->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1488
1478
to->cursor->ha_start_bulk_insert(from->cursor->stats.records);
1490
List<CreateField>::iterator it(create.begin());
1480
List_iterator<CreateField> it(create);
1491
1481
CreateField *def;
1492
1482
copy_end= copy;
1493
1483
for (Field **ptr= to->getFields(); *ptr ; ptr++)
1525
1515
from->sort.io_cache= new internal::IO_CACHE;
1527
1517
tables.table= from;
1528
tables.setTableName(from->getMutableShare()->getTableName());
1529
tables.alias= tables.getTableName();
1518
tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1519
tables.alias= const_cast<char *>(tables.getTableName());
1530
1520
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,
1523
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1524
setup_order(session, session->lex->select_lex.ref_pointer_array,
1535
1525
&tables, fields, all_fields, order) ||
1536
1526
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1537
1527
(from->sort.found_records= filesort.run(from, sortorder, length,
1638
1628
Ensure that the new table is saved properly to disk so that we
1639
1629
can do a rename
1641
if (transaction_services.autocommitOrRollback(*session, false))
1631
if (transaction_services.autocommitOrRollback(session, false))
1644
1634
if (not session->endActiveTransaction())