~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/create_table.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-13 01:03:01 UTC
  • mto: (1126.9.2 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090913010301-tcvvezipx1124acy
Added calls to the dtrace delete begin/end probes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include "config.h"
 
21
#include <drizzled/server_includes.h>
22
22
#include <drizzled/show.h>
23
23
#include <drizzled/lock.h>
24
24
#include <drizzled/session.h>
25
25
#include <drizzled/statement/create_table.h>
26
 
#include <drizzled/table_identifier.h>
27
 
 
28
 
#include <iostream>
29
 
 
30
 
namespace drizzled
31
 
{
 
26
 
 
27
using namespace drizzled;
32
28
 
33
29
bool statement::CreateTable::execute()
34
30
{
40
36
  bool need_start_waiting= false;
41
37
  bool res= false;
42
38
  bool link_to_local= false;
43
 
  bool lex_identified_temp_table= 
44
 
    create_table_message.type() == message::Table::TEMPORARY;
45
 
 
46
 
  if (is_engine_set)
47
 
  {
48
 
    create_info.db_type= 
49
 
      plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
50
 
 
51
 
    if (create_info.db_type == NULL)
52
 
    {
53
 
      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), 
54
 
               create_table_message.name().c_str());
55
 
 
56
 
      return true;
57
 
    }
58
 
  }
59
 
  else /* We now get the default, place it in create_info, and put the engine name in table proto */
60
 
  {
61
 
    create_info.db_type= session->getDefaultStorageEngine();
62
 
  }
63
 
 
64
 
  /* 
65
 
    Now we set the name in our Table proto so that it will match 
66
 
    create_info.db_type.
67
 
  */
68
 
  {
69
 
    message::Table::StorageEngine *protoengine;
70
 
 
71
 
    protoengine= create_table_message.mutable_engine();
72
 
    protoengine->set_name(create_info.db_type->getName());
73
 
  }
74
 
 
75
39
 
76
40
  /* If CREATE TABLE of non-temporary table, do implicit commit */
77
 
  if (not lex_identified_temp_table)
 
41
  if (! (session->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
78
42
  {
79
 
    if (not session->endActiveTransaction())
 
43
    if (! session->endActiveTransaction())
80
44
    {
81
45
      return true;
82
46
    }
84
48
  /* Skip first table, which is the table we are creating */
85
49
  TableList *create_table= session->lex->unlink_first_table(&link_to_local);
86
50
  TableList *select_tables= session->lex->query_tables;
87
 
 
88
 
 
89
 
  /*
90
 
    Now that we have the engine, we can figure out the table identifier. We need the engine in order
91
 
    to determine if the table is transactional or not if it is temp.
92
 
  */
93
 
 
94
 
  create_table_message.set_schema(create_table->db);
95
 
 
96
 
  TableIdentifier new_table_identifier(create_table->db,
97
 
                                       create_table->table_name,
98
 
                                       create_table_message.type());
99
 
 
100
 
  if (create_table_precheck(new_table_identifier))
 
51
  /*
 
52
     Code below (especially in mysql_create_table() and select_create
 
53
     methods) may modify HA_CREATE_INFO structure in LEX, so we have to
 
54
     use a copy of this structure to make execution prepared statement-
 
55
     safe. A shallow copy is enough as this code won't modify any memory
 
56
     referenced from this structure.
 
57
   */
 
58
  HA_CREATE_INFO create_info(session->lex->create_info);
 
59
  /*
 
60
     We need to copy alter_info for the same reasons of re-execution
 
61
     safety, only in case of Alter_info we have to do (almost) a deep
 
62
     copy.
 
63
   */
 
64
  Alter_info alter_info(session->lex->alter_info, session->mem_root);
 
65
 
 
66
  if (session->is_fatal_error)
 
67
  {
 
68
    /* If out of memory when creating a copy of alter_info. */
 
69
    /* put tables back for PS rexecuting */
 
70
    session->lex->link_first_table_back(create_table, link_to_local);
 
71
    return true;
 
72
  }
 
73
 
 
74
  if (create_table_precheck(session, select_tables, create_table))
101
75
  {
102
76
    /* put tables back for PS rexecuting */
103
77
    session->lex->link_first_table_back(create_table, link_to_local);
126
100
    session->lex->link_first_table_back(create_table, link_to_local);
127
101
    return true;
128
102
  }
129
 
 
130
103
  if (select_lex->item_list.elements)           // With select
131
104
  {
132
105
    select_result *result;
134
107
    select_lex->options|= SELECT_NO_UNLOCK;
135
108
    unit->set_limit(select_lex);
136
109
 
137
 
    if (not lex_identified_temp_table)
 
110
    if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
138
111
    {
139
112
      session->lex->link_first_table_back(create_table, link_to_local);
140
113
      create_table->create= true;
141
114
    }
142
115
 
143
 
    if (not (res= session->openTablesLock(session->lex->query_tables)))
 
116
    if (! (res= session->openTablesLock(session->lex->query_tables)))
144
117
    {
145
118
      /*
146
119
         Is table which we are changing used somewhere in other parts
147
120
         of query
148
121
       */
149
 
      if (not lex_identified_temp_table)
 
122
      if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
150
123
      {
151
124
        TableList *duplicate= NULL;
152
125
        create_table= session->lex->unlink_first_table(&link_to_local);
153
 
        if ((duplicate= unique_table(create_table, select_tables)))
 
126
        if ((duplicate= unique_table(session, create_table, select_tables, 0)))
154
127
        {
155
128
          my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
156
129
          /*
169
142
         needs to be created for every execution of a PS/SP.
170
143
       */
171
144
      if ((result= new select_create(create_table,
172
 
                                     is_if_not_exists,
173
145
                                     &create_info,
174
 
                                     create_table_message,
 
146
                                     session->lex->create_table_proto,
175
147
                                     &alter_info,
176
148
                                     select_lex->item_list,
177
149
                                     session->lex->duplicates,
178
150
                                     session->lex->ignore,
179
 
                                     select_tables,
180
 
                                     new_table_identifier)))
 
151
                                     select_tables)))
181
152
      {
182
153
        /*
183
154
           CREATE from SELECT give its Select_Lex for SELECT,
187
158
        delete result;
188
159
      }
189
160
    }
190
 
    else if (not lex_identified_temp_table)
 
161
    else if (! (create_info.options & HA_LEX_CREATE_TMP_TABLE))
191
162
    {
192
163
      create_table= session->lex->unlink_first_table(&link_to_local);
193
164
    }
194
165
  }
195
166
  else
196
167
  {
 
168
    /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
 
169
    if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
170
      session->options|= OPTION_KEEP_LOG;
197
171
    /* regular create */
198
 
    if (is_create_table_like)
 
172
    if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
199
173
    {
200
174
      res= mysql_create_like_table(session, 
201
 
                                   new_table_identifier,
202
175
                                   create_table, 
203
176
                                   select_tables,
204
 
                                   create_table_message,
205
 
                                   is_if_not_exists,
206
 
                                   is_engine_set);
 
177
                                   &create_info);
207
178
    }
208
179
    else
209
180
    {
210
 
 
211
 
      for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++)
212
 
      {
213
 
        message::Table::Field *field= create_table_message.add_field();
214
 
 
215
 
        *field= alter_info.alter_proto.added_field(x);
216
 
      }
217
 
 
218
181
      res= mysql_create_table(session, 
219
 
                              new_table_identifier,
 
182
                              create_table->db,
 
183
                              create_table->table_name, 
220
184
                              &create_info,
221
 
                              create_table_message,
 
185
                              session->lex->create_table_proto,
222
186
                              &alter_info, 
223
 
                              false, 
224
 
                              0,
225
 
                              is_if_not_exists);
 
187
                              0, 
 
188
                              0);
226
189
    }
227
 
 
228
 
    if (not res)
 
190
    if (! res)
229
191
    {
230
192
      session->my_ok();
231
193
    }
239
201
 
240
202
  return res;
241
203
}
242
 
 
243
 
} /* namespace drizzled */
244