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>
32 #include <drizzled/catalog/instance.h>
39 CreateTable::CreateTable(Session *in_session, Table_ident *ident,
bool is_temporary) :
43 on_update_value(NULL),
45 is_create_table_like(false),
46 lex_identified_temp_table(false),
48 create_table_list(NULL)
50 set_command(SQLCOM_CREATE_TABLE);
51 createTableMessage().set_name(ident->table.data(), ident->table.size());
53 createTableMessage().set_schema(ident->db.data(), ident->db.size());
56 createTableMessage().set_type(is_temporary ? message::Table::TEMPORARY : message::Table::STANDARD);
59 CreateTable::CreateTable(Session *in_session) :
63 on_update_value(NULL),
65 is_create_table_like(false),
66 lex_identified_temp_table(false),
68 create_table_list(NULL)
70 set_command(SQLCOM_CREATE_TABLE);
78 TableList *all_tables= lex().query_tables;
79 assert(first_table == all_tables && first_table != 0);
80 lex_identified_temp_table= createTableMessage().type() == message::Table::TEMPORARY;
82 is_engine_set= not createTableMessage().engine().name().empty();
86 create_info().db_type=
87 plugin::StorageEngine::findByName(session(), createTableMessage().engine().name());
89 if (create_info().db_type == NULL)
91 my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0),
92 createTableMessage().engine().name().c_str());
102 if (not validateCreateTableOption())
107 if (not lex_identified_temp_table)
109 if (session().inTransaction())
111 my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
116 create_table_list= lex().unlink_first_table(&link_to_local);
118 drizzled::message::table::init(createTableMessage(), createTableMessage().name(), create_table_list->getSchemaName(), create_info().db_type->getName());
121 create_table_list->getSchemaName(),
122 create_table_list->getTableName(),
123 createTableMessage().type());
125 if (not check(new_table_identifier))
128 lex().link_first_table_back(create_table_list, link_to_local);
133 create_info().alias= create_table_list->alias;
148 if (session().wait_if_global_read_lock(0, 1))
151 lex().link_first_table_back(create_table_list, link_to_local);
155 bool res= executeInner(new_table_identifier);
161 session().startWaitingGlobalReadLock();
166 bool statement::CreateTable::executeInner(
const identifier::Table& new_table_identifier)
169 Select_Lex *select_lex= &lex().select_lex;
170 TableList *select_tables= lex().query_tables;
174 if (select_lex->item_list.size())
176 Select_Lex_Unit *unit= &lex().unit;
179 select_lex->options|= SELECT_NO_UNLOCK;
180 unit->set_limit(select_lex);
182 if (not lex_identified_temp_table)
184 lex().link_first_table_back(create_table_list, link_to_local);
185 create_table_list->setCreate(
true);
188 if (not (res= session().openTablesLock(lex().query_tables)))
194 if (not lex_identified_temp_table)
196 create_table_list= lex().unlink_first_table(&link_to_local);
198 if (unique_table(create_table_list, select_tables))
200 my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias);
202 lex().link_first_table_back(create_table_list, link_to_local);
213 if ((result=
new select_create(create_table_list,
216 createTableMessage(),
218 select_lex->item_list,
222 new_table_identifier)))
232 else if (not lex_identified_temp_table)
234 create_table_list= lex().unlink_first_table(&link_to_local);
240 if (is_create_table_like)
242 res= create_like_table(&session(),
243 new_table_identifier,
244 identifier::Table(session().catalog().identifier(),
245 select_tables->getSchemaName(),
246 select_tables->getTableName()),
247 createTableMessage(),
254 for (int32_t x= 0; x < alter_info.added_fields_proto.added_field_size(); x++)
256 message::Table::Field *field= createTableMessage().add_field();
258 *field= alter_info.added_fields_proto.added_field(x);
261 res= create_table(&session(),
262 new_table_identifier,
264 createTableMessage(),
281 bool statement::CreateTable::check(
const identifier::Table &identifier)
284 if (not identifier.isValid())
290 identifier::Schema schema_identifier= identifier;
291 error::access(*session().user(), schema_identifier);
298 if (not plugin::StorageEngine::doesSchemaExist(identifier))
300 identifier::Schema schema_identifier= identifier;
301 my_error(ER_BAD_DB_ERROR, schema_identifier);
309 bool statement::CreateTable::validateCreateTableOption()
312 size_t num_engine_options= createTableMessage().engine().options_size();
314 assert(create_info().db_type);
316 for (
size_t y= 0; y < num_engine_options; ++y)
318 bool valid= create_info().db_type->validateCreateTableOption(createTableMessage().engine().options(y).name(),
319 createTableMessage().engine().options(y).state());
323 my_error(ER_UNKNOWN_ENGINE_OPTION, MYF(0),
324 createTableMessage().engine().options(y).name().c_str(),
325 createTableMessage().engine().options(y).state().c_str());
void my_ok(ha_rows affected_rows=0, ha_rows found_rows_arg=0, uint64_t passed_id=0, const char *message=NULL)
static bool canCreateTable(const drizzled::identifier::Table &identifier)
bool handle_select(Session *session, LEX *lex, select_result *result, uint64_t setup_tables_done_option)
plugin::StorageEngine * getDefaultStorageEngine()