~drizzle-trunk/drizzle/development

1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2009 Sun Microsystems
5
 *
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.
10
 *
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.
15
 *
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
19
 */
20
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
21
#include "config.h"
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
22
#include <drizzled/show.h>
23
#include <drizzled/lock.h>
24
#include <drizzled/session.h>
25
#include <drizzled/statement/create_table.h>
1223.4.1 by Brian Aker
Table Identifier patch.
26
#include <drizzled/table_identifier.h>
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
27
1130.3.12 by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/
28
namespace drizzled
29
{
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
30
31
bool statement::CreateTable::execute()
32
{
33
  TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
34
  TableList *all_tables= session->lex->query_tables;
35
  assert(first_table == all_tables && first_table != 0);
36
  Select_Lex *select_lex= &session->lex->select_lex;
37
  Select_Lex_Unit *unit= &session->lex->unit;
38
  bool need_start_waiting= false;
39
  bool res= false;
40
  bool link_to_local= false;
1222.2.2 by Brian Aker
Remove last ofl HA_CREATE_INFO being involved with temporary tables (always
41
  bool lex_identified_temp_table= 
42
    create_table_proto.type() == drizzled::message::Table::TEMPORARY;
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
43
1222.1.3 by Brian Aker
Remove used flag for engine.
44
  if (is_engine_set)
1160.1.5 by Brian Aker
Final parser SE removal.
45
  {
46
    create_info.db_type= 
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
47
      plugin::StorageEngine::findByName(*session, create_table_proto.engine().name());
1160.1.5 by Brian Aker
Final parser SE removal.
48
49
    if (create_info.db_type == NULL)
50
    {
51
      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), 
52
               create_table_proto.name().c_str());
53
54
      return true;
55
    }
56
  }
57
  else /* We now get the default, place it in create_info, and put the engine name in table proto */
58
  {
1183.1.1 by Brian Aker
Rework interface pieces on SE (sort of... dumb ones...)
59
    create_info.db_type= session->getDefaultStorageEngine();
1160.1.5 by Brian Aker
Final parser SE removal.
60
  }
61
1172.1.1 by Brian Aker
Add in support for ENGINE= in create table like.
62
1160.1.5 by Brian Aker
Final parser SE removal.
63
  /* 
64
    Now we set the name in our Table proto so that it will match 
65
    create_info.db_type.
66
  */
67
  {
68
    message::Table::StorageEngine *protoengine;
69
70
    protoengine= create_table_proto.mutable_engine();
71
    protoengine->set_name(create_info.db_type->getName());
72
  }
73
1172.1.1 by Brian Aker
Add in support for ENGINE= in create table like.
74
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
75
  /* If CREATE TABLE of non-temporary table, do implicit commit */
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
76
  if (! lex_identified_temp_table)
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
77
  {
78
    if (! session->endActiveTransaction())
79
    {
80
      return true;
81
    }
82
  }
83
  /* Skip first table, which is the table we are creating */
84
  TableList *create_table= session->lex->unlink_first_table(&link_to_local);
85
  TableList *select_tables= session->lex->query_tables;
1128.2.3 by Brian Aker
Remove create_info from global
86
1223.4.1 by Brian Aker
Table Identifier patch.
87
1235.1.3 by Brian Aker
Remove the need for trans/non-trans temp tables for lock conditions.
88
  /*
1223.4.1 by Brian Aker
Table Identifier patch.
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.
91
  */
92
  TableIdentifier new_table_identifier(create_table->db,
1223.4.3 by Brian Aker
More identifier work.
93
                                       create_table->table_name,
1235.1.3 by Brian Aker
Remove the need for trans/non-trans temp tables for lock conditions.
94
                                       create_table_proto.type() != message::Table::TEMPORARY ? NO_TMP_TABLE : TEMP_TABLE);
1223.4.1 by Brian Aker
Table Identifier patch.
95
96
  if (create_table_precheck(new_table_identifier))
1100.3.67 by Padraig O'Sullivan
Various small style cleanups.
97
  {
98
    /* put tables back for PS rexecuting */
99
    session->lex->link_first_table_back(create_table, link_to_local);
100
    return true;
101
  }
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
102
103
  /* Might have been updated in create_table_precheck */
104
  create_info.alias= create_table->alias;
105
106
  /*
107
     The create-select command will open and read-lock the select table
108
     and then create, open and write-lock the new table. If a global
109
     read lock steps in, we get a deadlock. The write lock waits for
110
     the global read lock, while the global read lock waits for the
111
     select table to be closed. So we wait until the global readlock is
112
     gone before starting both steps. Note that
113
     wait_if_global_read_lock() sets a protection against a new global
114
     read lock when it succeeds. This needs to be released by
115
     start_waiting_global_read_lock(). We protect the normal CREATE
116
     TABLE in the same way. That way we avoid that a new table is
117
     created during a gobal read lock.
118
   */
119
  if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
120
  {
1100.3.67 by Padraig O'Sullivan
Various small style cleanups.
121
    /* put tables back for PS rexecuting */
122
    session->lex->link_first_table_back(create_table, link_to_local);
123
    return true;
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
124
  }
1172.1.1 by Brian Aker
Add in support for ENGINE= in create table like.
125
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
126
  if (select_lex->item_list.elements)		// With select
127
  {
128
    select_result *result;
129
130
    select_lex->options|= SELECT_NO_UNLOCK;
131
    unit->set_limit(select_lex);
132
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
133
    if (! lex_identified_temp_table)
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
134
    {
135
      session->lex->link_first_table_back(create_table, link_to_local);
136
      create_table->create= true;
137
    }
138
139
    if (! (res= session->openTablesLock(session->lex->query_tables)))
140
    {
141
      /*
142
         Is table which we are changing used somewhere in other parts
143
         of query
144
       */
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
145
      if (! lex_identified_temp_table)
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
146
      {
147
        TableList *duplicate= NULL;
148
        create_table= session->lex->unlink_first_table(&link_to_local);
1220.1.13 by Brian Aker
Remove mysql_lock_have_duplicate() (we don't have merge, and our partition
149
        if ((duplicate= unique_table(create_table, select_tables)))
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
150
        {
151
          my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
1100.3.67 by Padraig O'Sullivan
Various small style cleanups.
152
          /*
153
             Release the protection against the global read lock and wake
154
             everyone, who might want to set a global read lock.
155
           */
156
          start_waiting_global_read_lock(session);
157
          /* put tables back for PS rexecuting */
158
          session->lex->link_first_table_back(create_table, link_to_local);
159
          return true;
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
160
        }
161
      }
162
163
      /*
164
         select_create is currently not re-execution friendly and
165
         needs to be created for every execution of a PS/SP.
166
       */
167
      if ((result= new select_create(create_table,
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
168
                                     is_if_not_exists,
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
169
                                     &create_info,
1128.2.2 by Brian Aker
Refactor to remove Proto from global.
170
                                     &create_table_proto,
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
171
                                     &alter_info,
172
                                     select_lex->item_list,
173
                                     session->lex->duplicates,
174
                                     session->lex->ignore,
175
                                     select_tables)))
176
      {
177
        /*
178
           CREATE from SELECT give its Select_Lex for SELECT,
179
           and item_list belong to SELECT
180
         */
181
        res= handle_select(session, session->lex, result, 0);
182
        delete result;
183
      }
184
    }
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
185
    else if (! lex_identified_temp_table)
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
186
    {
187
      create_table= session->lex->unlink_first_table(&link_to_local);
188
    }
189
  }
190
  else
191
  {
192
    /* regular create */
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
193
    if (is_create_table_like)
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
194
    {
195
      res= mysql_create_like_table(session, 
196
                                   create_table, 
197
                                   select_tables,
1172.1.1 by Brian Aker
Add in support for ENGINE= in create table like.
198
                                   create_table_proto,
1222.1.9 by Brian Aker
One more bit of HA_CREATE_INFO gone.
199
                                   create_info.db_type, 
1222.1.3 by Brian Aker
Remove used flag for engine.
200
                                   is_if_not_exists,
201
                                   is_engine_set);
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
202
    }
203
    else
204
    {
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
205
1220.1.11 by Brian Aker
Committing Stewart's work
206
      for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
207
      {
1220.1.11 by Brian Aker
Committing Stewart's work
208
        message::Table::Field *field= create_table_proto.add_field();
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
209
1220.1.11 by Brian Aker
Committing Stewart's work
210
        *field= alter_info.alter_proto.added_field(x);
1215.1.1 by stewart at flamingspork
[patch 01/17] horrible hack to have one lonely codepath produce Fields in the table proto
211
      }
212
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
213
      res= mysql_create_table(session, 
1223.4.1 by Brian Aker
Table Identifier patch.
214
                              new_table_identifier,
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
215
                              &create_info,
1128.2.2 by Brian Aker
Refactor to remove Proto from global.
216
                              &create_table_proto,
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
217
                              &alter_info, 
1223.4.3 by Brian Aker
More identifier work.
218
                              false, 
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
219
                              0,
220
                              is_if_not_exists);
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
221
    }
222
    if (! res)
223
    {
224
      session->my_ok();
225
    }
226
  }
227
228
  /*
229
     Release the protection against the global read lock and wake
230
     everyone, who might want to set a global read lock.
231
   */
232
  start_waiting_global_read_lock(session);
1100.3.67 by Padraig O'Sullivan
Various small style cleanups.
233
1100.3.65 by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation
234
  return res;
235
}
1130.3.12 by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/
236
237
} /* namespace drizzled */
238