~vkolesnikov/pbxt/pbxt-preload-test-bug

« back to all changes in this revision

Viewing changes to src/discover_xt.cc

  • Committer: Paul McCullagh
  • Date: 2009-11-10 15:17:41 UTC
  • Revision ID: paul.mccullagh@primebase.org-20091110151741-skjch5yqshrilo14
Merged changes required to compile with Drizzle

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <drizzled/session.h>
32
32
#include <drizzled/server_includes.h>
33
33
#include <drizzled/sql_base.h>
 
34
#include <drizzled/statement/alter_table.h>
 
35
#include <algorithm>
 
36
#include <sstream>
34
37
#endif
35
38
 
36
39
#include "strutil_xt.h"
46
49
#endif
47
50
#endif
48
51
 
49
 
#ifndef DRIZZLED
 
52
//#ifndef DRIZZLED
50
53
#define LOCK_OPEN_HACK_REQUIRED
51
 
#endif // DRIZZLED
 
54
//#endif // DRIZZLED
52
55
 
53
56
#ifdef LOCK_OPEN_HACK_REQUIRED
 
57
#ifdef DRIZZLED
 
58
 
 
59
using namespace drizzled;
 
60
using namespace std;
 
61
 
 
62
#define mysql_create_table_no_lock hacked_mysql_create_table_no_lock
 
63
 
 
64
namespace drizzled {
 
65
 
 
66
int rea_create_table(Session *session, const char *path,
 
67
                     const char *db, const char *table_name,
 
68
                     message::Table *table_proto,
 
69
                     HA_CREATE_INFO *create_info,
 
70
                     List<CreateField> &create_field,
 
71
                     uint32_t key_count,KEY *key_info);
 
72
}
 
73
 
 
74
static uint32_t build_tmptable_filename(Session* session,
 
75
                                        char *buff, size_t bufflen)
 
76
{
 
77
  uint32_t length;
 
78
  ostringstream path_str, post_tmpdir_str;
 
79
  string tmp;
 
80
 
 
81
  path_str << drizzle_tmpdir;
 
82
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
 
83
  post_tmpdir_str << session->thread_id << session->tmp_table++;
 
84
  tmp= post_tmpdir_str.str();
 
85
 
 
86
  transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
 
87
 
 
88
  path_str << tmp;
 
89
 
 
90
  if (bufflen < path_str.str().length())
 
91
    length= 0;
 
92
  else
 
93
    length= unpack_filename(buff, path_str.str().c_str());
 
94
 
 
95
  return length;
 
96
}
 
97
 
 
98
bool mysql_create_table_no_lock(Session *session,
 
99
                                const char *db, const char *table_name,
 
100
                                HA_CREATE_INFO *create_info,
 
101
                                message::Table *table_proto,
 
102
                                AlterInfo *alter_info,
 
103
                                bool internal_tmp_table,
 
104
                                uint32_t select_field_count)
 
105
{
 
106
  char          path[FN_REFLEN];
 
107
  uint32_t          path_length;
 
108
  uint          db_options, key_count;
 
109
  KEY           *key_info_buffer;
 
110
  Cursor        *file;
 
111
  bool          error= true;
 
112
  /* Check for duplicate fields and check type of table to create */
 
113
  if (!alter_info->create_list.elements)
 
114
  {
 
115
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
 
116
               MYF(0));
 
117
    return true;
 
118
  }
 
119
  assert(strcmp(table_name,table_proto->name().c_str())==0);
 
120
  if (check_engine(session, table_name, create_info))
 
121
    return true;
 
122
  db_options= create_info->table_options;
 
123
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
 
124
    db_options|=HA_OPTION_PACK_RECORD;
 
125
  
 
126
  /*if (!(file= create_info->db_type->getCursor((TableShare*) 0, session->mem_root)))
 
127
  {
 
128
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Cursor));
 
129
    return true;
 
130
  }*/
 
131
 
 
132
  /* PMC - Done to avoid getting the partition handler by mistake! */
 
133
  if (!(file= new (session->mem_root) ha_xtsys(pbxt_hton, NULL)))
 
134
  {
 
135
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Cursor));
 
136
    return true;
 
137
  }
 
138
 
 
139
  set_table_default_charset(create_info, (char*) db);
 
140
 
 
141
  if (mysql_prepare_create_table(session, create_info, alter_info,
 
142
                                 internal_tmp_table,
 
143
                                 &db_options, file,
 
144
                                 &key_info_buffer, &key_count,
 
145
                                 select_field_count))
 
146
    goto err;
 
147
 
 
148
      /* Check if table exists */
 
149
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
150
  {
 
151
    path_length= build_tmptable_filename(session, path, sizeof(path));
 
152
  }
 
153
  else
 
154
  {
 
155
 #ifdef FN_DEVCHAR
 
156
    /* check if the table name contains FN_DEVCHAR when defined */
 
157
    if (strchr(table_name, FN_DEVCHAR))
 
158
    {
 
159
      my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name);
 
160
      return true;
 
161
    }
 
162
#endif
 
163
    path_length= build_table_filename(path, sizeof(path), db, table_name, internal_tmp_table);
 
164
  }
 
165
 
 
166
  /* Check if table already exists */
 
167
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
 
168
      session->find_temporary_table(db, table_name))
 
169
  {
 
170
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
 
171
    {
 
172
      create_info->table_existed= 1;            // Mark that table existed
 
173
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
174
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
 
175
                          table_name);
 
176
      error= 0;
 
177
      goto err;
 
178
    }
 
179
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
 
180
    goto err;
 
181
  }
 
182
 
 
183
  //pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
 
184
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
 
185
  {
 
186
    if (plugin::StorageEngine::getTableProto(path, NULL)==EEXIST)
 
187
    {
 
188
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
 
189
      {
 
190
        error= false;
 
191
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
192
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
 
193
                            table_name);
 
194
        create_info->table_existed= 1;          // Mark that table existed
 
195
      }
 
196
      else
 
197
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
 
198
 
 
199
      goto unlock_and_end;
 
200
    }
 
201
    /*
 
202
 *       We don't assert here, but check the result, because the table could be
 
203
 *             in the table definition cache and in the same time the .frm could be
 
204
 *                   missing from the disk, in case of manual intervention which deletes
 
205
 *                         the .frm file. The user has to use FLUSH TABLES; to clear the cache.
 
206
 *                               Then she could create the table. This case is pretty obscure and
 
207
 *                                     therefore we don't introduce a new error message only for it.
 
208
 *                                         */
 
209
    if (TableShare::getShare(db, table_name))
 
210
    {
 
211
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
 
212
      goto unlock_and_end;
 
213
    }
 
214
  }
 
215
  /*
 
216
 *     Check that table with given name does not already
 
217
 *         exist in any storage engine. In such a case it should
 
218
 *             be discovered and the error ER_TABLE_EXISTS_ERROR be returned
 
219
 *                 unless user specified CREATE TABLE IF EXISTS
 
220
 *                     The LOCK_open mutex has been locked to make sure no
 
221
 *                         one else is attempting to discover the table. Since
 
222
 *                             it's not on disk as a frm file, no one could be using it!
 
223
 *                               */
 
224
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
 
225
  {
 
226
    bool create_if_not_exists =
 
227
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
 
228
 
 
229
    char table_path[FN_REFLEN];
 
230
    uint32_t          table_path_length;
 
231
 
 
232
    table_path_length= build_table_filename(table_path, sizeof(table_path),
 
233
                                            db, table_name, false);
 
234
 
 
235
    int retcode= plugin::StorageEngine::getTableProto(table_path, NULL);
 
236
    switch (retcode)
 
237
    {
 
238
      case ENOENT:
 
239
        /* Normal case, no table exists. we can go and create it */
 
240
        break;
 
241
      case EEXIST:
 
242
        if (create_if_not_exists)
 
243
        {
 
244
          error= false;
 
245
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
246
                              ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
 
247
                              table_name);
 
248
          create_info->table_existed= 1;                // Mark that table existed
 
249
          goto unlock_and_end;
 
250
        }
 
251
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
 
252
        goto unlock_and_end;
 
253
      default:
 
254
        my_error(retcode, MYF(0),table_name);
 
255
        goto unlock_and_end;
 
256
    }
 
257
  }
 
258
 
 
259
  session->set_proc_info("creating table");
 
260
  create_info->table_existed= 0;                // Mark that table is created
 
261
 
 
262
  create_info->table_options=db_options;
 
263
 
 
264
  if (rea_create_table(session, path, db, table_name,
 
265
                       table_proto,
 
266
                       create_info, alter_info->create_list,
 
267
                       key_count, key_info_buffer))
 
268
    goto unlock_and_end;
 
269
 
 
270
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
271
  {
 
272
    /* Open table and put in temporary table list */
 
273
    if (!(session->open_temporary_table(path, db, table_name, 1, OTM_OPEN)))
 
274
    {
 
275
      (void) session->rm_temporary_table(create_info->db_type, path);
 
276
      goto unlock_and_end;
 
277
    }
 
278
  }
 
279
 
 
280
  /*
 
281
 *     Don't write statement if:
 
282
 *         - It is an internal temporary table,
 
283
 *             - Row-based logging is used and it we are creating a temporary table, or
 
284
 *                 - The binary log is not open.
 
285
 *                     Otherwise, the statement shall be binlogged.
 
286
 *                        */
 
287
  if (!internal_tmp_table &&
 
288
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
289
    write_bin_log(session, session->query, session->query_length);
 
290
  error= false;
 
291
unlock_and_end:
 
292
  //pthread_mutex_unlock(&LOCK_open);
 
293
 
 
294
err:
 
295
  session->set_proc_info("After create");
 
296
  delete file;
 
297
  return(error);
 
298
}
 
299
 
 
300
#else // MySQL case
54
301
///////////////////////////////
55
302
/*
56
303
 * Unfortunately I cannot use the standard mysql_create_table_no_lock() because it will lock "LOCK_open"
1279
1526
////// END OF CUT AND PASTES FROM  sql_table.cc ////////
1280
1527
////////////////////////////////////////////////////////
1281
1528
 
 
1529
#endif // DRIZZLED
1282
1530
#endif // LOCK_OPEN_HACK_REQUIRED
1283
1531
 
1284
1532
//------------------------------
1285
1533
int xt_create_table_frm(handlerton *hton, THD* thd, const char *db, const char *name, DT_FIELD_INFO *info, DT_KEY_INFO *XT_UNUSED(keys), xtBool skip_existing)
1286
1534
{
1287
1535
#ifdef DRIZZLED
1288
 
    drizzled::message::Table table_proto;
 
1536
#define MYLEX_CREATE_INFO create_info
 
1537
#else
 
1538
#define MYLEX_CREATE_INFO mylex.create_info 
 
1539
#endif
 
1540
 
 
1541
#ifdef DRIZZLED
 
1542
        drizzled::statement::AlterTable *stmt = new drizzled::statement::AlterTable(thd);
 
1543
        HA_CREATE_INFO create_info;
 
1544
        //AlterInfo alter_info;
 
1545
        drizzled::message::Table table_proto;
1289
1546
 
1290
1547
        static const char *ext = ".dfe";
1291
1548
        static const int ext_len = 4;
 
1549
 
 
1550
        table_proto.mutable_engine()->mutable_name()->assign("PBXT");
1292
1551
#else
1293
1552
        static const char *ext = ".frm";
1294
1553
        static const int ext_len = 4;
1295
1554
#endif
1296
1555
        int err = 1;
1297
 
        //HA_CREATE_INFO create_info = {0};
1298
 
        //Alter_info alter_info;
1299
1556
        char field_length_buffer[12], *field_length_ptr;
1300
1557
        LEX  *save_lex= thd->lex, mylex;
1301
 
        
1302
 
        memset(&mylex.create_info, 0, sizeof(HA_CREATE_INFO));
 
1558
 
 
1559
        memset(&MYLEX_CREATE_INFO, 0, sizeof(HA_CREATE_INFO));
1303
1560
 
1304
1561
        thd->lex = &mylex;
1305
 
    lex_start(thd);
 
1562
        lex_start(thd);
 
1563
#ifdef DRIZZLED
 
1564
        mylex.statement = stmt;
 
1565
#endif
1306
1566
        
1307
1567
        /* setup the create info */
1308
 
        mylex.create_info.db_type = hton;
 
1568
        MYLEX_CREATE_INFO.db_type = hton;
 
1569
 
1309
1570
#ifndef DRIZZLED 
1310
1571
        mylex.create_info.frm_only = 1;
1311
1572
#endif
1312
 
        mylex.create_info.default_table_charset = system_charset_info;
 
1573
        MYLEX_CREATE_INFO.default_table_charset = system_charset_info;
1313
1574
        
1314
1575
        /* setup the column info. */
1315
1576
        while (info->field_name) {              
1369
1630
    table_proto.set_name(name);
1370
1631
    table_proto.set_type(drizzled::message::Table::STANDARD);
1371
1632
 
1372
 
        if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &table_proto, &mylex.alter_info, 1, 0, false)) 
 
1633
        if (mysql_create_table_no_lock(thd, db, name, &create_info, &table_proto, &stmt->alter_info, 1, 0)) 
1373
1634
                goto error;
1374
1635
#else
1375
1636
        if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0))