18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include <drizzled/server_includes.h>
22
22
#include <drizzled/show.h>
23
23
#include <drizzled/lock.h>
24
24
#include <drizzled/session.h>
25
25
#include <drizzled/statement/create_table.h>
26
#include <drizzled/message.h>
27
#include <drizzled/identifier.h>
27
using namespace drizzled;
34
29
bool statement::CreateTable::execute()
41
36
bool need_start_waiting= false;
43
38
bool link_to_local= false;
44
bool lex_identified_temp_table=
45
create_table_message.type() == message::Table::TEMPORARY;
50
plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
52
if (create_info.db_type == NULL)
54
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
55
create_table_message.engine().name().c_str());
60
else /* We now get the default, place it in create_info, and put the engine name in table proto */
62
create_info.db_type= session->getDefaultStorageEngine();
65
if (not validateCreateTableOption())
71
40
/* If CREATE TABLE of non-temporary table, do implicit commit */
72
if (not lex_identified_temp_table)
41
if (! (session->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
74
if (not session->endActiveTransaction())
43
if (! session->endActiveTransaction())
79
48
/* Skip first table, which is the table we are creating */
80
49
TableList *create_table= session->lex->unlink_first_table(&link_to_local);
81
50
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 (not check(new_table_identifier))
52
Code below (especially in mysql_create_table() and select_create
53
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
54
use a copy of this structure to make execution prepared statement-
55
safe. A shallow copy is enough as this code won't modify any memory
56
referenced from this structure.
58
HA_CREATE_INFO create_info(session->lex->create_info);
60
We need to copy alter_info for the same reasons of re-execution
61
safety, only in case of AlterInfo we have to do (almost) a deep
64
AlterInfo alter_info(session->lex->alter_info, session->mem_root);
66
if (session->is_fatal_error)
68
/* If out of memory when creating a copy of alter_info. */
69
/* put tables back for PS rexecuting */
70
session->lex->link_first_table_back(create_table, link_to_local);
74
if (create_table_precheck(session, select_tables, create_table))
91
76
/* put tables back for PS rexecuting */
92
77
session->lex->link_first_table_back(create_table, link_to_local);
109
94
TABLE in the same way. That way we avoid that a new table is
110
95
created during a gobal read lock.
112
if (! (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
97
if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
114
99
/* put tables back for PS rexecuting */
115
100
session->lex->link_first_table_back(create_table, link_to_local);
119
103
if (select_lex->item_list.elements) // With select
121
105
select_result *result;
123
107
select_lex->options|= SELECT_NO_UNLOCK;
124
108
unit->set_limit(select_lex);
126
if (not lex_identified_temp_table)
110
if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
128
112
session->lex->link_first_table_back(create_table, link_to_local);
129
create_table->setCreate(true);
113
create_table->create= true;
132
if (not (res= session->openTablesLock(session->lex->query_tables)))
116
if (! (res= session->openTablesLock(session->lex->query_tables)))
135
119
Is table which we are changing used somewhere in other parts
138
if (not lex_identified_temp_table)
122
if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
140
124
TableList *duplicate= NULL;
141
125
create_table= session->lex->unlink_first_table(&link_to_local);
142
if ((duplicate= unique_table(create_table, select_tables)))
126
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
144
128
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
146
130
Release the protection against the global read lock and wake
147
131
everyone, who might want to set a global read lock.
149
session->startWaitingGlobalReadLock();
133
start_waiting_global_read_lock(session);
150
134
/* put tables back for PS rexecuting */
151
135
session->lex->link_first_table_back(create_table, link_to_local);
159
142
needs to be created for every execution of a PS/SP.
161
144
if ((result= new select_create(create_table,
164
create_table_message,
146
session->lex->create_table_proto,
166
148
select_lex->item_list,
167
149
session->lex->duplicates,
168
150
session->lex->ignore,
170
new_table_identifier)))
173
154
CREATE from SELECT give its Select_Lex for SELECT,
180
else if (not lex_identified_temp_table)
161
else if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
182
163
create_table= session->lex->unlink_first_table(&link_to_local);
168
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
169
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
170
session->options|= OPTION_KEEP_LOG;
187
171
/* regular create */
188
if (is_create_table_like)
172
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
190
174
res= mysql_create_like_table(session,
191
new_table_identifier,
194
create_table_message,
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
181
res= mysql_create_table(session,
209
new_table_identifier,
183
create_table->table_name,
211
create_table_message,
185
session->lex->create_table_proto,
220
192
session->my_ok();
225
197
Release the protection against the global read lock and wake
226
198
everyone, who might want to set a global read lock.
228
session->startWaitingGlobalReadLock();
200
start_waiting_global_read_lock(session);
233
bool statement::CreateTable::check(const TableIdentifier &identifier)
235
// Check table name for validity
236
if (not identifier.isValid())
239
// See if any storage engine objects to the name of the file
240
if (not plugin::StorageEngine::canCreateTable(identifier))
242
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", identifier.getSchemaName().c_str());
247
// Make sure the schema exists, we will do this again during the actual
248
// create for the table.
249
if (not plugin::StorageEngine::doesSchemaExist(identifier))
251
my_error(ER_BAD_DB_ERROR, MYF(0), identifier.getSchemaName().c_str());
259
bool statement::CreateTable::validateCreateTableOption()
262
size_t num_engine_options= create_table_message.engine().options_size();
264
assert(create_info.db_type);
266
for (size_t y= 0; y < num_engine_options; ++y)
268
bool valid= create_info.db_type->validateCreateTableOption(create_table_message.engine().options(y).name(),
269
create_table_message.engine().options(y).state());
273
my_error(ER_UNKNOWN_ENGINE_OPTION, MYF(0),
274
create_table_message.engine().options(y).name().c_str(),
275
create_table_message.engine().options(y).state().c_str());
284
} /* namespace drizzled */