~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/create_table.cc

  • Committer: Brian Aker
  • Date: 2011-01-12 06:45:23 UTC
  • mto: (2073.1.4 catalogs)
  • mto: This revision was merged to the branch mainline in revision 2080.
  • Revision ID: brian@tangent.org-20110112064523-rqhptaqbph22qmj1
Remove custom error.

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>
22
 
 
 
21
#include "config.h"
23
22
#include <drizzled/show.h>
24
23
#include <drizzled/lock.h>
25
24
#include <drizzled/session.h>
26
25
#include <drizzled/statement/create_table.h>
27
26
#include <drizzled/message.h>
28
27
#include <drizzled/identifier.h>
29
 
#include <drizzled/plugin/storage_engine.h>
30
 
#include <drizzled/select_create.h>
31
28
 
32
29
#include <iostream>
33
30
 
34
31
namespace drizzled
35
32
{
36
33
 
37
 
namespace statement {
38
 
 
39
 
CreateTable::CreateTable(Session *in_session, Table_ident *ident, bool is_temporary) :
40
 
  Statement(in_session),
41
 
  change(NULL),
42
 
  default_value(NULL),
43
 
  on_update_value(NULL),
44
 
  is_engine_set(false),
45
 
  is_create_table_like(false),
46
 
  lex_identified_temp_table(false),
47
 
  link_to_local(false),
48
 
  create_table_list(NULL)
49
 
{
50
 
  getSession()->getLex()->sql_command= SQLCOM_CREATE_TABLE;
51
 
  createTableMessage().set_name(ident->table.str, ident->table.length);
52
 
#if 0
53
 
  createTableMessage().set_schema(ident->db.str, ident->db.length);
54
 
#endif
55
 
 
56
 
  if (is_temporary)
57
 
  {
58
 
    createTableMessage().set_type(message::Table::TEMPORARY);
59
 
  }
60
 
  else
61
 
  {
62
 
    createTableMessage().set_type(message::Table::STANDARD);
63
 
  }
64
 
}
65
 
 
66
 
CreateTable::CreateTable(Session *in_session) :
67
 
  Statement(in_session),
68
 
  change(NULL),
69
 
  default_value(NULL),
70
 
  on_update_value(NULL),
71
 
  is_engine_set(false),
72
 
  is_create_table_like(false),
73
 
  lex_identified_temp_table(false),
74
 
  link_to_local(false),
75
 
  create_table_list(NULL)
76
 
{
77
 
  getSession()->getLex()->sql_command= SQLCOM_CREATE_TABLE;
78
 
}
79
 
 
80
 
} // namespace statement
81
 
 
82
34
bool statement::CreateTable::execute()
83
35
{
84
 
  TableList *first_table= (TableList *) getSession()->getLex()->select_lex.table_list.first;
85
 
  TableList *all_tables= getSession()->getLex()->query_tables;
 
36
  TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
 
37
  TableList *all_tables= session->lex->query_tables;
86
38
  assert(first_table == all_tables && first_table != 0);
87
39
  bool need_start_waiting= false;
88
40
  lex_identified_temp_table= createTableMessage().type() == message::Table::TEMPORARY;
92
44
  if (is_engine_set)
93
45
  {
94
46
    create_info().db_type= 
95
 
      plugin::StorageEngine::findByName(*getSession(), createTableMessage().engine().name());
 
47
      plugin::StorageEngine::findByName(*session, createTableMessage().engine().name());
96
48
 
97
49
    if (create_info().db_type == NULL)
98
50
    {
104
56
  }
105
57
  else /* We now get the default, place it in create_info, and put the engine name in table proto */
106
58
  {
107
 
    create_info().db_type= getSession()->getDefaultStorageEngine();
 
59
    create_info().db_type= session->getDefaultStorageEngine();
108
60
  }
109
61
 
110
62
  if (not validateCreateTableOption())
112
64
    return true;
113
65
  }
114
66
 
 
67
 
 
68
  /* If CREATE TABLE of non-temporary table, do implicit commit */
115
69
  if (not lex_identified_temp_table)
116
70
  {
117
 
    if (getSession()->inTransaction())
 
71
    if (not session->endActiveTransaction())
118
72
    {
119
 
      my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
120
73
      return true;
121
74
    }
122
75
  }
123
76
  /* Skip first table, which is the table we are creating */
124
 
  create_table_list= getSession()->getLex()->unlink_first_table(&link_to_local);
 
77
  create_table_list= session->lex->unlink_first_table(&link_to_local);
125
78
 
126
79
  drizzled::message::table::init(createTableMessage(), createTableMessage().name(), create_table_list->getSchemaName(), create_info().db_type->getName());
127
80
 
128
 
  identifier::Table new_table_identifier(create_table_list->getSchemaName(),
 
81
  TableIdentifier new_table_identifier(create_table_list->getSchemaName(),
129
82
                                       create_table_list->getTableName(),
130
83
                                       createTableMessage().type());
131
84
 
132
85
  if (not check(new_table_identifier))
133
86
  {
134
87
    /* put tables back for PS rexecuting */
135
 
    getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
 
88
    session->lex->link_first_table_back(create_table_list, link_to_local);
136
89
    return true;
137
90
  }
138
91
 
152
105
     TABLE in the same way. That way we avoid that a new table is
153
106
     created during a gobal read lock.
154
107
   */
155
 
  if (! (need_start_waiting= not getSession()->wait_if_global_read_lock(0, 1)))
 
108
  if (! (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
156
109
  {
157
110
    /* put tables back for PS rexecuting */
158
 
    getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
 
111
    session->lex->link_first_table_back(create_table_list, link_to_local);
159
112
    return true;
160
113
  }
161
114
 
165
118
    Release the protection against the global read lock and wake
166
119
    everyone, who might want to set a global read lock.
167
120
  */
168
 
  getSession()->startWaitingGlobalReadLock();
 
121
  session->startWaitingGlobalReadLock();
169
122
 
170
123
  return res;
171
124
}
172
125
 
173
 
bool statement::CreateTable::executeInner(identifier::Table::const_reference new_table_identifier)
 
126
bool statement::CreateTable::executeInner(TableIdentifier::const_reference new_table_identifier)
174
127
{
175
128
  bool res= false;
176
 
  Select_Lex *select_lex= &getSession()->getLex()->select_lex;
177
 
  TableList *select_tables= getSession()->getLex()->query_tables;
 
129
  Select_Lex *select_lex= &session->lex->select_lex;
 
130
  TableList *select_tables= session->lex->query_tables;
178
131
 
179
 
  do 
180
 
  {
 
132
  do {
181
133
    if (select_lex->item_list.elements)         // With select
182
134
    {
183
 
      Select_Lex_Unit *unit= &getSession()->getLex()->unit;
 
135
      Select_Lex_Unit *unit= &session->lex->unit;
184
136
      select_result *result;
185
137
 
186
138
      select_lex->options|= SELECT_NO_UNLOCK;
188
140
 
189
141
      if (not lex_identified_temp_table)
190
142
      {
191
 
        getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
 
143
        session->lex->link_first_table_back(create_table_list, link_to_local);
192
144
        create_table_list->setCreate(true);
193
145
      }
194
146
 
195
 
      if (not (res= getSession()->openTablesLock(getSession()->getLex()->query_tables)))
 
147
      if (not (res= session->openTablesLock(session->lex->query_tables)))
196
148
      {
197
149
        /*
198
150
          Is table which we are changing used somewhere in other parts
201
153
        if (not lex_identified_temp_table)
202
154
        {
203
155
          TableList *duplicate= NULL;
204
 
          create_table_list= getSession()->getLex()->unlink_first_table(&link_to_local);
 
156
          create_table_list= session->lex->unlink_first_table(&link_to_local);
205
157
 
206
158
          if ((duplicate= unique_table(create_table_list, select_tables)))
207
159
          {
208
160
            my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias);
209
161
            /* put tables back for PS rexecuting */
210
 
            getSession()->getLex()->link_first_table_back(create_table_list, link_to_local);
 
162
            session->lex->link_first_table_back(create_table_list, link_to_local);
211
163
 
212
164
            res= true;
213
165
            break;
219
171
          needs to be created for every execution of a PS/SP.
220
172
        */
221
173
        if ((result= new select_create(create_table_list,
222
 
                                       getSession()->getLex()->exists(),
 
174
                                       session->getLex()->exists(),
223
175
                                       &create_info(),
224
176
                                       createTableMessage(),
225
177
                                       &alter_info,
226
178
                                       select_lex->item_list,
227
 
                                       getSession()->getLex()->duplicates,
228
 
                                       getSession()->getLex()->ignore,
 
179
                                       session->lex->duplicates,
 
180
                                       session->lex->ignore,
229
181
                                       select_tables,
230
182
                                       new_table_identifier)))
231
183
        {
233
185
            CREATE from SELECT give its Select_Lex for SELECT,
234
186
            and item_list belong to SELECT
235
187
          */
236
 
          res= handle_select(getSession(), getSession()->getLex(), result, 0);
 
188
          res= handle_select(session, session->lex, result, 0);
237
189
          delete result;
238
190
        }
239
191
      }
240
192
      else if (not lex_identified_temp_table)
241
193
      {
242
 
        create_table_list= getSession()->getLex()->unlink_first_table(&link_to_local);
 
194
        create_table_list= session->lex->unlink_first_table(&link_to_local);
243
195
      }
244
196
    }
245
197
    else
247
199
      /* regular create */
248
200
      if (is_create_table_like)
249
201
      {
250
 
        res= create_like_table(getSession(), 
 
202
        res= create_like_table(session, 
251
203
                               new_table_identifier,
252
 
                               identifier::Table(select_tables->getSchemaName(),
253
 
                                                 select_tables->getTableName()),
 
204
                               create_table_list, 
 
205
                               select_tables,
254
206
                               createTableMessage(),
255
 
                               getSession()->getLex()->exists(),
 
207
                               session->getLex()->exists(),
256
208
                               is_engine_set);
257
209
      }
258
210
      else
265
217
          *field= alter_info.alter_proto.added_field(x);
266
218
        }
267
219
 
268
 
        res= create_table(getSession(), 
 
220
        res= create_table(session, 
269
221
                          new_table_identifier,
270
222
                          &create_info(),
271
223
                          createTableMessage(),
272
224
                          &alter_info, 
273
225
                          false, 
274
226
                          0,
275
 
                          getSession()->getLex()->exists());
 
227
                          session->getLex()->exists());
276
228
      }
277
229
 
278
230
      if (not res)
279
231
      {
280
 
        getSession()->my_ok();
 
232
        session->my_ok();
281
233
      }
282
234
    }
283
235
  } while (0);
285
237
  return res;
286
238
}
287
239
 
288
 
bool statement::CreateTable::check(const identifier::Table &identifier)
 
240
bool statement::CreateTable::check(const TableIdentifier &identifier)
289
241
{
290
242
  // Check table name for validity
291
243
  if (not identifier.isValid())
294
246
  // See if any storage engine objects to the name of the file
295
247
  if (not plugin::StorageEngine::canCreateTable(identifier))
296
248
  {
297
 
    identifier::Schema schema_identifier= identifier;
298
 
    error::access(*getSession()->user(), schema_identifier);
 
249
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", identifier.getSchemaName().c_str());
299
250
 
300
251
    return false;
301
252
  }
304
255
  // create for the table.
305
256
  if (not plugin::StorageEngine::doesSchemaExist(identifier))
306
257
  {
307
 
    identifier::Schema schema_identifier= identifier;
308
 
    my_error(ER_BAD_DB_ERROR, schema_identifier);
 
258
    my_error(ER_BAD_DB_ERROR, MYF(0), identifier.getSchemaName().c_str());
309
259
 
310
260
    return false;
311
261
  }