1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include <drizzled/server_includes.h>
22
#include <drizzled/show.h>
23
#include <drizzled/lock.h>
24
#include <drizzled/session.h>
25
#include <drizzled/statement/create_table.h>
27
using namespace drizzled;
29
bool statement::CreateTable::execute()
31
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
32
TableList *all_tables= session->lex->query_tables;
33
assert(first_table == all_tables && first_table != 0);
34
Select_Lex *select_lex= &session->lex->select_lex;
35
Select_Lex_Unit *unit= &session->lex->unit;
36
bool need_start_waiting= false;
38
bool link_to_local= false;
40
/* If CREATE TABLE of non-temporary table, do implicit commit */
41
if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
43
if (! session->endActiveTransaction())
48
/* Skip first table, which is the table we are creating */
49
TableList *create_table= session->lex->unlink_first_table(&link_to_local);
50
TableList *select_tables= session->lex->query_tables;
52
if (create_table_precheck(session, select_tables, create_table))
54
/* put tables back for PS rexecuting */
55
session->lex->link_first_table_back(create_table, link_to_local);
59
/* Might have been updated in create_table_precheck */
60
create_info.alias= create_table->alias;
63
The create-select command will open and read-lock the select table
64
and then create, open and write-lock the new table. If a global
65
read lock steps in, we get a deadlock. The write lock waits for
66
the global read lock, while the global read lock waits for the
67
select table to be closed. So we wait until the global readlock is
68
gone before starting both steps. Note that
69
wait_if_global_read_lock() sets a protection against a new global
70
read lock when it succeeds. This needs to be released by
71
start_waiting_global_read_lock(). We protect the normal CREATE
72
TABLE in the same way. That way we avoid that a new table is
73
created during a gobal read lock.
75
if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
77
/* put tables back for PS rexecuting */
78
session->lex->link_first_table_back(create_table, link_to_local);
81
if (select_lex->item_list.elements) // With select
83
select_result *result;
85
select_lex->options|= SELECT_NO_UNLOCK;
86
unit->set_limit(select_lex);
88
if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
90
session->lex->link_first_table_back(create_table, link_to_local);
91
create_table->create= true;
94
if (! (res= session->openTablesLock(session->lex->query_tables)))
97
Is table which we are changing used somewhere in other parts
100
if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
102
TableList *duplicate= NULL;
103
create_table= session->lex->unlink_first_table(&link_to_local);
104
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
106
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
108
Release the protection against the global read lock and wake
109
everyone, who might want to set a global read lock.
111
start_waiting_global_read_lock(session);
112
/* put tables back for PS rexecuting */
113
session->lex->link_first_table_back(create_table, link_to_local);
119
select_create is currently not re-execution friendly and
120
needs to be created for every execution of a PS/SP.
122
if ((result= new select_create(create_table,
126
select_lex->item_list,
127
session->lex->duplicates,
128
session->lex->ignore,
132
CREATE from SELECT give its Select_Lex for SELECT,
133
and item_list belong to SELECT
135
res= handle_select(session, session->lex, result, 0);
139
else if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
141
create_table= session->lex->unlink_first_table(&link_to_local);
146
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
147
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
148
session->options|= OPTION_KEEP_LOG;
150
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
152
res= mysql_create_like_table(session,
159
res= mysql_create_table(session,
161
create_table->table_name,
175
Release the protection against the global read lock and wake
176
everyone, who might want to set a global read lock.
178
start_waiting_global_read_lock(session);