18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
22
#include <drizzled/show.h>
24
23
#include <drizzled/lock.h>
25
24
#include <drizzled/session.h>
26
25
#include <drizzled/statement/create_table.h>
27
26
#include <drizzled/message.h>
28
27
#include <drizzled/identifier.h>
29
#include <drizzled/plugin/storage_engine.h>
30
#include <drizzled/select_create.h>
32
29
#include <iostream>
39
CreateTable::CreateTable(Session *in_session, Table_ident *ident, bool is_temporary) :
40
Statement(in_session),
43
on_update_value(NULL),
45
is_create_table_like(false),
46
lex_identified_temp_table(false),
48
create_table_list(NULL)
50
getSession()->getLex()->sql_command= SQLCOM_CREATE_TABLE;
51
createTableMessage().set_name(ident->table.str, ident->table.length);
53
createTableMessage().set_schema(ident->db.str, ident->db.length);
58
createTableMessage().set_type(message::Table::TEMPORARY);
62
createTableMessage().set_type(message::Table::STANDARD);
66
CreateTable::CreateTable(Session *in_session) :
67
Statement(in_session),
70
on_update_value(NULL),
72
is_create_table_like(false),
73
lex_identified_temp_table(false),
75
create_table_list(NULL)
77
getSession()->getLex()->sql_command= SQLCOM_CREATE_TABLE;
80
} // namespace statement
82
34
bool statement::CreateTable::execute()
84
TableList *first_table= (TableList *) getSession()->getLex()->select_lex.table_list.first;
85
TableList *all_tables= getSession()->getLex()->query_tables;
36
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
37
TableList *all_tables= session->lex->query_tables;
86
38
assert(first_table == all_tables && first_table != 0);
39
Select_Lex *select_lex= &session->lex->select_lex;
40
Select_Lex_Unit *unit= &session->lex->unit;
87
41
bool need_start_waiting= false;
88
lex_identified_temp_table= createTableMessage().type() == message::Table::TEMPORARY;
90
is_engine_set= not createTableMessage().engine().name().empty();
43
bool link_to_local= false;
44
bool lex_identified_temp_table=
45
create_table_message.type() == message::Table::TEMPORARY;
94
create_info().db_type=
95
plugin::StorageEngine::findByName(*getSession(), createTableMessage().engine().name());
50
plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
97
if (create_info().db_type == NULL)
52
if (create_info.db_type == NULL)
99
54
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
100
createTableMessage().engine().name().c_str());
55
create_table_message.engine().name().c_str());
105
60
else /* We now get the default, place it in create_info, and put the engine name in table proto */
107
create_info().db_type= getSession()->getDefaultStorageEngine();
62
create_info.db_type= session->getDefaultStorageEngine();
110
65
if (not validateCreateTableOption())
71
/* If CREATE TABLE of non-temporary table, do implicit commit */
115
72
if (not lex_identified_temp_table)
117
if (getSession()->inTransaction())
74
if (not session->endActiveTransaction())
119
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
123
79
/* Skip first table, which is the table we are creating */
124
create_table_list= getSession()->getLex()->unlink_first_table(&link_to_local);
126
drizzled::message::table::init(createTableMessage(), createTableMessage().name(), create_table_list->getSchemaName(), create_info().db_type->getName());
128
identifier::Table new_table_identifier(create_table_list->getSchemaName(),
129
create_table_list->getTableName(),
130
createTableMessage().type());
132
if (not check(new_table_identifier))
80
TableList *create_table= session->lex->unlink_first_table(&link_to_local);
81
TableList *select_tables= session->lex->query_tables;
83
drizzled::message::init(create_table_message, create_table_message.name(), create_table->getSchemaName(), create_info.db_type->getName());
85
TableIdentifier new_table_identifier(create_table->getSchemaName(),
86
create_table->getTableName(),
87
create_table_message.type());
89
if (create_table_precheck(new_table_identifier))
134
91
/* put tables back for PS rexecuting */
135
getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
92
session->lex->link_first_table_back(create_table, link_to_local);
139
96
/* Might have been updated in create_table_precheck */
140
create_info().alias= create_table_list->alias;
97
create_info.alias= create_table->alias;
143
100
The create-select command will open and read-lock the select table
152
109
TABLE in the same way. That way we avoid that a new table is
153
110
created during a gobal read lock.
155
if (! (need_start_waiting= not getSession()->wait_if_global_read_lock(0, 1)))
112
if (! (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
157
114
/* put tables back for PS rexecuting */
158
getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
115
session->lex->link_first_table_back(create_table, link_to_local);
162
bool res= executeInner(new_table_identifier);
165
Release the protection against the global read lock and wake
166
everyone, who might want to set a global read lock.
168
getSession()->startWaitingGlobalReadLock();
173
bool statement::CreateTable::executeInner(identifier::Table::const_reference new_table_identifier)
176
Select_Lex *select_lex= &getSession()->getLex()->select_lex;
177
TableList *select_tables= getSession()->getLex()->query_tables;
119
if (select_lex->item_list.elements) // With select
181
if (select_lex->item_list.elements) // With select
183
Select_Lex_Unit *unit= &getSession()->getLex()->unit;
184
select_result *result;
186
select_lex->options|= SELECT_NO_UNLOCK;
187
unit->set_limit(select_lex);
121
select_result *result;
123
select_lex->options|= SELECT_NO_UNLOCK;
124
unit->set_limit(select_lex);
126
if (not lex_identified_temp_table)
128
session->lex->link_first_table_back(create_table, link_to_local);
129
create_table->setCreate(true);
132
if (not (res= session->openTablesLock(session->lex->query_tables)))
135
Is table which we are changing used somewhere in other parts
189
138
if (not lex_identified_temp_table)
191
getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
192
create_table_list->setCreate(true);
195
if (not (res= getSession()->openTablesLock(getSession()->getLex()->query_tables)))
198
Is table which we are changing used somewhere in other parts
201
if (not lex_identified_temp_table)
203
TableList *duplicate= NULL;
204
create_table_list= getSession()->getLex()->unlink_first_table(&link_to_local);
206
if ((duplicate= unique_table(create_table_list, select_tables)))
208
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias);
209
/* put tables back for PS rexecuting */
210
getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
218
select_create is currently not re-execution friendly and
219
needs to be created for every execution of a PS/SP.
221
if ((result= new select_create(create_table_list,
222
getSession()->getLex()->exists(),
224
createTableMessage(),
226
select_lex->item_list,
227
getSession()->getLex()->duplicates,
228
getSession()->getLex()->ignore,
230
new_table_identifier)))
140
TableList *duplicate= NULL;
141
create_table= session->lex->unlink_first_table(&link_to_local);
142
if ((duplicate= unique_table(create_table, select_tables)))
144
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
233
CREATE from SELECT give its Select_Lex for SELECT,
234
and item_list belong to SELECT
236
res= handle_select(getSession(), getSession()->getLex(), result, 0);
146
Release the protection against the global read lock and wake
147
everyone, who might want to set a global read lock.
149
session->startWaitingGlobalReadLock();
150
/* put tables back for PS rexecuting */
151
session->lex->link_first_table_back(create_table, link_to_local);
240
else if (not lex_identified_temp_table)
158
select_create is currently not re-execution friendly and
159
needs to be created for every execution of a PS/SP.
161
if ((result= new select_create(create_table,
164
create_table_message,
166
select_lex->item_list,
167
session->lex->duplicates,
168
session->lex->ignore,
170
new_table_identifier)))
242
create_table_list= getSession()->getLex()->unlink_first_table(&link_to_local);
173
CREATE from SELECT give its Select_Lex for SELECT,
174
and item_list belong to SELECT
176
res= handle_select(session, session->lex, result, 0);
180
else if (not lex_identified_temp_table)
182
create_table= session->lex->unlink_first_table(&link_to_local);
188
if (is_create_table_like)
190
res= mysql_create_like_table(session,
191
new_table_identifier,
194
create_table_message,
248
if (is_create_table_like)
250
res= create_like_table(getSession(),
251
new_table_identifier,
252
identifier::Table(select_tables->getSchemaName(),
253
select_tables->getTableName()),
254
createTableMessage(),
255
getSession()->getLex()->exists(),
261
for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
263
message::Table::Field *field= createTableMessage().add_field();
265
*field= alter_info.alter_proto.added_field(x);
268
res= create_table(getSession(),
269
new_table_identifier,
271
createTableMessage(),
275
getSession()->getLex()->exists());
280
getSession()->my_ok();
201
for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
203
message::Table::Field *field= create_table_message.add_field();
205
*field= alter_info.alter_proto.added_field(x);
208
res= mysql_create_table(session,
209
new_table_identifier,
211
create_table_message,
225
Release the protection against the global read lock and wake
226
everyone, who might want to set a global read lock.
228
session->startWaitingGlobalReadLock();
288
bool statement::CreateTable::check(const identifier::Table &identifier)
290
// Check table name for validity
291
if (not identifier.isValid())
294
// See if any storage engine objects to the name of the file
295
if (not plugin::StorageEngine::canCreateTable(identifier))
297
identifier::Schema schema_identifier= identifier;
298
error::access(*getSession()->user(), schema_identifier);
303
// Make sure the schema exists, we will do this again during the actual
304
// create for the table.
305
if (not plugin::StorageEngine::doesSchemaExist(identifier))
307
identifier::Schema schema_identifier= identifier;
308
my_error(ER_BAD_DB_ERROR, schema_identifier);
316
233
bool statement::CreateTable::validateCreateTableOption()
319
size_t num_engine_options= createTableMessage().engine().options_size();
236
size_t num_engine_options= create_table_message.engine().options_size();
321
assert(create_info().db_type);
238
assert(create_info.db_type);
323
240
for (size_t y= 0; y < num_engine_options; ++y)
325
bool valid= create_info().db_type->validateCreateTableOption(createTableMessage().engine().options(y).name(),
326
createTableMessage().engine().options(y).state());
242
bool valid= create_info.db_type->validateCreateTableOption(create_table_message.engine().options(y).name(),
243
create_table_message.engine().options(y).state());
330
247
my_error(ER_UNKNOWN_ENGINE_OPTION, MYF(0),
331
createTableMessage().engine().options(y).name().c_str(),
332
createTableMessage().engine().options(y).state().c_str());
248
create_table_message.engine().options(y).name().c_str(),
249
create_table_message.engine().options(y).state().c_str());