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>
26
#include <drizzled/table_identifier.h>
43
40
bool link_to_local= false;
44
41
bool lex_identified_temp_table=
45
create_table_message.type() == message::Table::TEMPORARY;
42
create_table_proto.type() == message::Table::TEMPORARY;
49
46
create_info.db_type=
50
plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
47
plugin::StorageEngine::findByName(*session, create_table_proto.engine().name());
52
49
if (create_info.db_type == NULL)
54
51
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
55
create_table_message.engine().name().c_str());
52
create_table_proto.name().c_str());
62
59
create_info.db_type= session->getDefaultStorageEngine();
65
if (not validateCreateTableOption())
64
Now we set the name in our Table proto so that it will match
68
message::Table::StorageEngine *protoengine;
70
protoengine= create_table_proto.mutable_engine();
71
protoengine->set_name(create_info.db_type->getName());
71
75
/* If CREATE TABLE of non-temporary table, do implicit commit */
72
if (not lex_identified_temp_table)
76
if (! lex_identified_temp_table)
74
if (not session->endActiveTransaction())
78
if (! session->endActiveTransaction())
80
84
TableList *create_table= session->lex->unlink_first_table(&link_to_local);
81
85
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))
89
Now that we have the engine, we can figure out the table identifier. We need the engine in order
90
to determine if the table is transactional or not if it is temp.
92
TableIdentifier new_table_identifier(create_table->db,
93
create_table->table_name,
94
create_table_proto.type() != message::Table::TEMPORARY ? NO_TMP_TABLE : TEMP_TABLE);
96
if (create_table_precheck(new_table_identifier))
91
98
/* put tables back for PS rexecuting */
92
99
session->lex->link_first_table_back(create_table, link_to_local);
109
116
TABLE in the same way. That way we avoid that a new table is
110
117
created during a gobal read lock.
112
if (! (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
119
if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
114
121
/* put tables back for PS rexecuting */
115
122
session->lex->link_first_table_back(create_table, link_to_local);
123
130
select_lex->options|= SELECT_NO_UNLOCK;
124
131
unit->set_limit(select_lex);
126
if (not lex_identified_temp_table)
133
if (! lex_identified_temp_table)
128
135
session->lex->link_first_table_back(create_table, link_to_local);
129
create_table->setCreate(true);
136
create_table->create= true;
132
if (not (res= session->openTablesLock(session->lex->query_tables)))
139
if (! (res= session->openTablesLock(session->lex->query_tables)))
135
142
Is table which we are changing used somewhere in other parts
138
if (not lex_identified_temp_table)
145
if (! lex_identified_temp_table)
140
147
TableList *duplicate= NULL;
141
148
create_table= session->lex->unlink_first_table(&link_to_local);
146
153
Release the protection against the global read lock and wake
147
154
everyone, who might want to set a global read lock.
149
session->startWaitingGlobalReadLock();
156
start_waiting_global_read_lock(session);
150
157
/* put tables back for PS rexecuting */
151
158
session->lex->link_first_table_back(create_table, link_to_local);
161
167
if ((result= new select_create(create_table,
162
168
is_if_not_exists,
164
create_table_message,
166
172
select_lex->item_list,
167
173
session->lex->duplicates,
168
174
session->lex->ignore,
170
new_table_identifier)))
173
178
CREATE from SELECT give its Select_Lex for SELECT,
201
206
for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
203
message::Table::Field *field= create_table_message.add_field();
208
message::Table::Field *field= create_table_proto.add_field();
205
210
*field= alter_info.alter_proto.added_field(x);
225
229
Release the protection against the global read lock and wake
226
230
everyone, who might want to set a global read lock.
228
session->startWaitingGlobalReadLock();
232
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
237
} /* namespace drizzled */