24 #include <drizzled/lock.h>
25 #include <drizzled/session.h>
26 #include <drizzled/statement/create_table.h>
27 #include <drizzled/message.h>
28 #include <drizzled/identifier.h>
29 #include <drizzled/plugin/storage_engine.h>
30 #include <drizzled/select_create.h>
31 #include <drizzled/table_ident.h>
38 CreateTable::CreateTable(Session *in_session, Table_ident *ident,
bool is_temporary) :
42 on_update_value(NULL),
44 is_create_table_like(false),
45 lex_identified_temp_table(false),
47 create_table_list(NULL)
49 set_command(SQLCOM_CREATE_TABLE);
50 createTableMessage().set_name(ident->table.data(), ident->table.size());
52 createTableMessage().set_schema(ident->db.data(), ident->db.size());
55 createTableMessage().set_type(is_temporary ? message::Table::TEMPORARY : message::Table::STANDARD);
58 CreateTable::CreateTable(Session *in_session) :
62 on_update_value(NULL),
64 is_create_table_like(false),
65 lex_identified_temp_table(false),
67 create_table_list(NULL)
69 set_command(SQLCOM_CREATE_TABLE);
77 TableList *all_tables= lex().query_tables;
78 assert(first_table == all_tables && first_table != 0);
79 lex_identified_temp_table= createTableMessage().type() == message::Table::TEMPORARY;
81 is_engine_set= not createTableMessage().engine().name().empty();
85 create_info().db_type=
86 plugin::StorageEngine::findByName(session(), createTableMessage().engine().name());
88 if (create_info().db_type == NULL)
90 my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
91 createTableMessage().engine().name().c_str());
101 if (not validateCreateTableOption())
106 if (not lex_identified_temp_table)
108 if (session().inTransaction())
110 my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
115 create_table_list= lex().unlink_first_table(&link_to_local);
117 drizzled::message::table::init(createTableMessage(), createTableMessage().name(), create_table_list->getSchemaName(), create_info().db_type->getName());
120 create_table_list->getTableName(),
121 createTableMessage().type());
123 if (not check(new_table_identifier))
126 lex().link_first_table_back(create_table_list, link_to_local);
131 create_info().alias= create_table_list->alias;
146 if (session().wait_if_global_read_lock(0, 1))
149 lex().link_first_table_back(create_table_list, link_to_local);
153 bool res= executeInner(new_table_identifier);
159 session().startWaitingGlobalReadLock();
164 bool statement::CreateTable::executeInner(
const identifier::Table& new_table_identifier)
167 Select_Lex *select_lex= &lex().select_lex;
168 TableList *select_tables= lex().query_tables;
172 if (select_lex->item_list.size())
174 Select_Lex_Unit *unit= &lex().unit;
177 select_lex->options|= SELECT_NO_UNLOCK;
178 unit->set_limit(select_lex);
180 if (not lex_identified_temp_table)
182 lex().link_first_table_back(create_table_list, link_to_local);
183 create_table_list->setCreate(
true);
186 if (not (res= session().openTablesLock(lex().query_tables)))
192 if (not lex_identified_temp_table)
194 create_table_list= lex().unlink_first_table(&link_to_local);
196 if (unique_table(create_table_list, select_tables))
198 my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias);
200 lex().link_first_table_back(create_table_list, link_to_local);
211 if ((result=
new select_create(create_table_list,
214 createTableMessage(),
216 select_lex->item_list,
220 new_table_identifier)))
230 else if (not lex_identified_temp_table)
232 create_table_list= lex().unlink_first_table(&link_to_local);
238 if (is_create_table_like)
240 res= create_like_table(&session(),
241 new_table_identifier,
242 identifier::Table(select_tables->getSchemaName(),
243 select_tables->getTableName()),
244 createTableMessage(),
251 for (int32_t x= 0; x < alter_info.added_fields_proto.added_field_size(); x++)
253 message::Table::Field *field= createTableMessage().add_field();
255 *field= alter_info.added_fields_proto.added_field(x);
258 res= create_table(&session(),
259 new_table_identifier,
261 createTableMessage(),
278 bool statement::CreateTable::check(
const identifier::Table &identifier)
281 if (not identifier.isValid())
287 identifier::Schema schema_identifier= identifier;
288 error::access(*session().user(), schema_identifier);
295 if (not plugin::StorageEngine::doesSchemaExist(identifier))
297 identifier::Schema schema_identifier= identifier;
298 my_error(ER_BAD_DB_ERROR, schema_identifier);
306 bool statement::CreateTable::validateCreateTableOption()
309 size_t num_engine_options= createTableMessage().engine().options_size();
311 assert(create_info().db_type);
313 for (
size_t y= 0; y < num_engine_options; ++y)
315 bool valid= create_info().db_type->validateCreateTableOption(createTableMessage().engine().options(y).name(),
316 createTableMessage().engine().options(y).state());
320 my_error(ER_UNKNOWN_ENGINE_OPTION, MYF(0),
321 createTableMessage().engine().options(y).name().c_str(),
322 createTableMessage().engine().options(y).state().c_str());