~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_proto_write.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:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include "config.h"
 
16
#include <drizzled/server_includes.h>
17
17
#include <drizzled/error.h>
18
18
#include <drizzled/session.h>
19
19
#include <drizzled/unireg.h>
20
 
#include "drizzled/sql_table.h"
21
 
#include "drizzled/global_charset_info.h"
22
 
#include "drizzled/message/statement_transform.h"
23
 
 
24
 
#include "drizzled/internal/my_sys.h"
25
 
 
26
20
 
27
21
/* For proto */
28
22
#include <string>
29
23
#include <fstream>
30
 
#include <fcntl.h>
31
24
#include <drizzled/message/schema.pb.h>
32
25
#include <drizzled/message/table.pb.h>
33
26
#include <google/protobuf/io/zero_copy_stream.h>
34
27
#include <google/protobuf/io/zero_copy_stream_impl.h>
35
28
 
36
29
#include <drizzled/table_proto.h>
37
 
 
38
30
using namespace std;
39
 
 
40
 
namespace drizzled {
41
 
 
42
 
static int fill_table_proto(message::Table &table_proto,
43
 
                            const std::string &table_name,
44
 
                            List<CreateField> &create_fields,
45
 
                            HA_CREATE_INFO *create_info,
46
 
                            uint32_t keys,
47
 
                            KEY *key_info)
 
31
using namespace drizzled;
 
32
 
 
33
int fill_table_proto(message::Table *table_proto,
 
34
                     const char *table_name,
 
35
                     List<CreateField> &create_fields,
 
36
                     HA_CREATE_INFO *create_info,
 
37
                     uint32_t keys,
 
38
                     KEY *key_info)
48
39
{
49
40
  CreateField *field_arg;
50
41
  List_iterator<CreateField> it(create_fields);
51
 
  message::Table::TableOptions *table_options= table_proto.mutable_options();
 
42
  message::Table::TableOptions *table_options= table_proto->mutable_options();
52
43
 
53
44
  if (create_fields.elements > MAX_FIELDS)
54
45
  {
56
47
    return(1);
57
48
  }
58
49
 
59
 
  assert(strcmp(table_proto.engine().name().c_str(),
 
50
  assert(strcmp(table_proto->engine().name().c_str(),
60
51
                create_info->db_type->getName().c_str())==0);
61
52
 
62
 
  assert(table_proto.name() == table_name);
 
53
  assert(strcmp(table_proto->name().c_str(),table_name)==0);
63
54
 
64
 
  int field_number= 0;
65
 
  bool use_existing_fields= table_proto.field_size() > 0;
66
55
  while ((field_arg= it++))
67
56
  {
68
57
    message::Table::Field *attribute;
69
58
 
70
 
    /* some (one) code path for CREATE TABLE fills the proto
71
 
       out more than the others, so we already have partially
72
 
       filled out Field messages */
73
 
 
74
 
    if (use_existing_fields)
75
 
      attribute= table_proto.mutable_field(field_number++);
76
 
    else
 
59
    attribute= table_proto->add_field();
 
60
    attribute->set_name(field_arg->field_name);
 
61
 
 
62
    attribute->set_pack_flag(field_arg->pack_flag); /* TODO: MUST DIE */
 
63
 
 
64
    if(f_maybe_null(field_arg->pack_flag))
77
65
    {
78
 
      /* Other code paths still have to fill out the proto */
79
 
      attribute= table_proto.add_field();
80
 
 
81
 
      if (field_arg->flags & NOT_NULL_FLAG)
82
 
      {
83
 
        message::Table::Field::FieldConstraints *constraints;
84
 
 
85
 
        constraints= attribute->mutable_constraints();
86
 
        constraints->set_is_nullable(false);
87
 
      }
88
 
 
89
 
      attribute->set_name(field_arg->field_name);
 
66
      message::Table::Field::FieldConstraints *constraints;
 
67
 
 
68
      constraints= attribute->mutable_constraints();
 
69
      constraints->set_is_nullable(true);
90
70
    }
91
71
 
92
 
    assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
93
 
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
94
 
 
95
 
 
96
 
    message::Table::Field::FieldType parser_type= attribute->type();
97
 
 
98
 
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
99
 
 
100
 
    switch (attribute->type()) {
101
 
    default: /* Only deal with types that need extra information */
102
 
      break;
103
 
    case message::Table::Field::DOUBLE:
104
 
      {
105
 
        /*
106
 
         * For DOUBLE, we only add a specific scale and precision iff
107
 
         * the fixed decimal point has been specified...
108
 
         */
109
 
        if (field_arg->decimals != NOT_FIXED_DEC)
110
 
        {
111
 
          message::Table::Field::NumericFieldOptions *numeric_field_options;
112
 
 
113
 
          numeric_field_options= attribute->mutable_numeric_options();
114
 
 
115
 
          numeric_field_options->set_precision(field_arg->length);
116
 
          numeric_field_options->set_scale(field_arg->decimals);
117
 
        }
118
 
      }
119
 
      break;
120
 
    case message::Table::Field::VARCHAR:
 
72
    switch (field_arg->sql_type) {
 
73
    case DRIZZLE_TYPE_TINY:
 
74
      attribute->set_type(message::Table::Field::TINYINT);
 
75
      break;
 
76
    case DRIZZLE_TYPE_LONG:
 
77
      attribute->set_type(message::Table::Field::INTEGER);
 
78
      break;
 
79
    case DRIZZLE_TYPE_DOUBLE:
 
80
      attribute->set_type(message::Table::Field::DOUBLE);
 
81
      break;
 
82
    case DRIZZLE_TYPE_NULL  :
 
83
      assert(1); /* Not a user definable type */
 
84
    case DRIZZLE_TYPE_TIMESTAMP:
 
85
      attribute->set_type(message::Table::Field::TIMESTAMP);
 
86
      break;
 
87
    case DRIZZLE_TYPE_LONGLONG:
 
88
      attribute->set_type(message::Table::Field::BIGINT);
 
89
      break;
 
90
    case DRIZZLE_TYPE_DATETIME:
 
91
      attribute->set_type(message::Table::Field::DATETIME);
 
92
      break;
 
93
    case DRIZZLE_TYPE_DATE:
 
94
      attribute->set_type(message::Table::Field::DATE);
 
95
      break;
 
96
    case DRIZZLE_TYPE_VARCHAR:
121
97
      {
122
98
        message::Table::Field::StringFieldOptions *string_field_options;
123
99
 
124
100
        string_field_options= attribute->mutable_string_options();
125
 
 
126
 
        if (! use_existing_fields || string_field_options->length()==0)
127
 
          string_field_options->set_length(field_arg->length
128
 
                                           / field_arg->charset->mbmaxlen);
129
 
        else
130
 
          assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
131
 
 
132
 
        if (! string_field_options->has_collation())
133
 
        {
134
 
          string_field_options->set_collation_id(field_arg->charset->number);
135
 
          string_field_options->set_collation(field_arg->charset->name);
136
 
        }
 
101
        attribute->set_type(message::Table::Field::VARCHAR);
 
102
        string_field_options->set_length(field_arg->length
 
103
                                         / field_arg->charset->mbmaxlen);
 
104
        string_field_options->set_collation_id(field_arg->charset->number);
 
105
        string_field_options->set_collation(field_arg->charset->name);
 
106
 
137
107
        break;
138
108
      }
139
 
    case message::Table::Field::DECIMAL:
 
109
    case DRIZZLE_TYPE_NEWDECIMAL:
140
110
      {
141
111
        message::Table::Field::NumericFieldOptions *numeric_field_options;
142
112
 
 
113
        attribute->set_type(message::Table::Field::DECIMAL);
143
114
        numeric_field_options= attribute->mutable_numeric_options();
144
115
        /* This is magic, I hate magic numbers -Brian */
145
116
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
146
117
        numeric_field_options->set_scale(field_arg->decimals);
147
118
        break;
148
119
      }
149
 
    case message::Table::Field::ENUM:
 
120
    case DRIZZLE_TYPE_ENUM:
150
121
      {
151
 
        message::Table::Field::EnumerationValues *enumeration_options;
 
122
        message::Table::Field::SetFieldOptions *set_field_options;
152
123
 
153
124
        assert(field_arg->interval);
154
125
 
155
 
        enumeration_options= attribute->mutable_enumeration_values();
 
126
        attribute->set_type(message::Table::Field::ENUM);
 
127
        set_field_options= attribute->mutable_set_options();
156
128
 
157
129
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
158
130
        {
159
131
          const char *src= field_arg->interval->type_names[pos];
160
132
 
161
 
          enumeration_options->add_field_value(src);
 
133
          set_field_options->add_field_value(src);
162
134
        }
163
 
        enumeration_options->set_collation_id(field_arg->charset->number);
164
 
        enumeration_options->set_collation(field_arg->charset->name);
 
135
        set_field_options->set_count_elements(set_field_options->field_value_size());
 
136
        set_field_options->set_collation_id(field_arg->charset->number);
 
137
        set_field_options->set_collation(field_arg->charset->name);
165
138
        break;
166
139
      }
167
 
    case message::Table::Field::BLOB:
 
140
    case DRIZZLE_TYPE_BLOB:
168
141
      {
 
142
        attribute->set_type(message::Table::Field::BLOB);
 
143
 
169
144
        message::Table::Field::StringFieldOptions *string_field_options;
170
145
 
171
146
        string_field_options= attribute->mutable_string_options();
174
149
      }
175
150
 
176
151
      break;
 
152
    default:
 
153
      assert(0); /* Tell us, since this shouldn't happend */
177
154
    }
178
155
 
179
 
    assert (!use_existing_fields || parser_type == attribute->type());
180
 
 
181
156
#ifdef NOTDONE
182
157
    field_constraints= attribute->mutable_constraints();
183
158
    constraints->set_is_nullable(field_arg->def->null_value);
217
192
        return(1);
218
193
      }
219
194
 
220
 
      if (! use_existing_fields)
221
 
        attribute->set_comment(field_arg->comment.str);
222
 
 
223
 
      assert(strcmp(attribute->comment().c_str(), field_arg->comment.str)==0);
 
195
      attribute->set_comment(field_arg->comment.str);
224
196
    }
225
197
 
226
 
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
 
198
    if(field_arg->unireg_check == Field::NEXT_NUMBER)
227
199
    {
228
200
      message::Table::Field::NumericFieldOptions *field_options;
229
201
      field_options= attribute->mutable_numeric_options();
230
202
      field_options->set_is_autoincrement(true);
231
203
    }
232
204
 
233
 
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
 
205
    if(field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
234
206
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
235
207
    {
236
208
      message::Table::Field::FieldOptions *field_options;
238
210
      field_options->set_default_value("NOW()");
239
211
    }
240
212
 
241
 
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
 
213
    if(field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
242
214
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
243
215
    {
244
216
      message::Table::Field::FieldOptions *field_options;
246
218
      field_options->set_update_value("NOW()");
247
219
    }
248
220
 
249
 
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
 
221
    if(field_arg->def)
250
222
    {
251
223
      message::Table::Field::FieldOptions *field_options;
252
224
      field_options= attribute->mutable_options();
253
225
 
254
 
      field_options->set_default_null(true);
255
 
    }
256
 
    if (field_arg->def)
257
 
    {
258
 
      message::Table::Field::FieldOptions *field_options;
259
 
      field_options= attribute->mutable_options();
260
 
 
261
 
      if (field_arg->def->is_null())
 
226
      if(field_arg->def->is_null())
262
227
      {
263
228
        field_options->set_default_null(true);
264
229
      }
269
234
 
270
235
        assert(default_value);
271
236
 
272
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
 
237
        if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
273
238
           || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
274
239
           && ((field_arg->length / field_arg->charset->mbmaxlen)
275
240
           < default_value->length()))
278
243
          return 1;
279
244
        }
280
245
 
281
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
 
246
        if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
282
247
            && field_arg->charset==&my_charset_bin)
283
248
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
284
249
            && field_arg->charset==&my_charset_bin))
295
260
      }
296
261
    }
297
262
 
 
263
    {
 
264
      message::Table::Field::FieldOptions *field_options;
 
265
      field_options= attribute->mutable_options();
 
266
 
 
267
      field_options->set_length(field_arg->length);
 
268
    }
 
269
 
298
270
    assert(field_arg->unireg_check == Field::NONE
299
271
           || field_arg->unireg_check == Field::NEXT_NUMBER
300
272
           || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
303
275
 
304
276
  }
305
277
 
306
 
  assert(! use_existing_fields || (field_number == table_proto.field_size()));
 
278
  switch(create_info->row_type)
 
279
  {
 
280
  case ROW_TYPE_DEFAULT:
 
281
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_DEFAULT);
 
282
    break;
 
283
  case ROW_TYPE_FIXED:
 
284
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_FIXED);
 
285
    break;
 
286
  case ROW_TYPE_DYNAMIC:
 
287
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_DYNAMIC);
 
288
    break;
 
289
  case ROW_TYPE_COMPRESSED:
 
290
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_COMPRESSED);
 
291
    break;
 
292
  case ROW_TYPE_REDUNDANT:
 
293
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_REDUNDANT);
 
294
    break;
 
295
  case ROW_TYPE_COMPACT:
 
296
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_COMPACT);
 
297
    break;
 
298
  case ROW_TYPE_PAGE:
 
299
    table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_PAGE);
 
300
    break;
 
301
  default:
 
302
    abort();
 
303
  }
307
304
 
308
 
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
309
 
    table_options->set_pack_record(true);
 
305
  table_options->set_pack_record(create_info->table_options
 
306
                                 & HA_OPTION_PACK_RECORD);
310
307
 
311
308
  if (table_options->has_comment())
312
309
  {
336
333
  if (create_info->auto_increment_value)
337
334
    table_options->set_auto_increment_value(create_info->auto_increment_value);
338
335
 
339
 
  for (uint32_t i= 0; i < keys; i++)
 
336
  if (create_info->key_block_size)
 
337
    table_options->set_key_block_size(create_info->key_block_size);
 
338
 
 
339
  if (create_info->block_size)
 
340
    table_options->set_block_size(create_info->block_size);
 
341
 
 
342
  for (unsigned int i= 0; i < keys; i++)
340
343
  {
341
344
    message::Table::Index *idx;
342
345
 
343
 
    idx= table_proto.add_indexes();
 
346
    idx= table_proto->add_indexes();
344
347
 
345
348
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
346
349
           (key_info[i].comment.length > 0));
349
352
 
350
353
    idx->set_key_length(key_info[i].key_length);
351
354
 
352
 
    if (is_primary_key_name(key_info[i].name))
 
355
    if(is_primary_key_name(key_info[i].name))
353
356
      idx->set_is_primary(true);
354
357
    else
355
358
      idx->set_is_primary(false);
364
367
      idx->set_type(message::Table::Index::BTREE);
365
368
      break;
366
369
 
 
370
    case HA_KEY_ALG_RTREE:
 
371
      idx->set_type(message::Table::Index::RTREE);
 
372
    case HA_KEY_ALG_FULLTEXT:
 
373
      idx->set_type(message::Table::Index::FULLTEXT);
367
374
    case HA_KEY_ALG_UNDEF:
368
375
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
369
376
      break;
379
386
 
380
387
    message::Table::Index::IndexOptions *index_options= idx->mutable_options();
381
388
 
382
 
    if (key_info[i].flags & HA_USES_BLOCK_SIZE)
 
389
    if(key_info[i].flags & HA_USES_BLOCK_SIZE)
383
390
      index_options->set_key_block_size(key_info[i].block_size);
384
391
 
385
 
    if (key_info[i].flags & HA_PACK_KEY)
 
392
    if(key_info[i].flags & HA_PACK_KEY)
386
393
      index_options->set_pack_key(true);
387
394
 
388
 
    if (key_info[i].flags & HA_BINARY_PACK_KEY)
 
395
    if(key_info[i].flags & HA_BINARY_PACK_KEY)
389
396
      index_options->set_binary_pack_key(true);
390
397
 
391
 
    if (key_info[i].flags & HA_VAR_LENGTH_PART)
 
398
    if(key_info[i].flags & HA_VAR_LENGTH_PART)
392
399
      index_options->set_var_length_key(true);
393
400
 
394
 
    if (key_info[i].flags & HA_NULL_PART_KEY)
 
401
    if(key_info[i].flags & HA_NULL_PART_KEY)
395
402
      index_options->set_null_part_key(true);
396
403
 
397
 
    if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
 
404
    if(key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
398
405
      index_options->set_has_partial_segments(true);
399
406
 
400
 
    if (key_info[i].flags & HA_GENERATED_KEY)
 
407
    if(key_info[i].flags & HA_GENERATED_KEY)
401
408
      index_options->set_auto_generated_key(true);
402
409
 
403
410
    if (key_info[i].flags & HA_USES_COMMENT)
419
426
 
420
427
      idx->set_comment(key_info[i].comment.str);
421
428
    }
422
 
    if (key_info[i].flags & 
423
 
        ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | 
424
 
          HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | 
425
 
          HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
 
429
    if(key_info[i].flags & ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
426
430
      abort(); // Invalid (unknown) index flag.
427
431
 
428
432
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
443
447
  return 0;
444
448
}
445
449
 
 
450
int rename_table_proto_file(const char *from, const char* to)
 
451
{
 
452
  string from_path(from);
 
453
  string to_path(to);
 
454
  string file_ext = ".dfe";
 
455
 
 
456
  from_path.append(file_ext);
 
457
  to_path.append(file_ext);
 
458
 
 
459
  return my_rename(from_path.c_str(),to_path.c_str(),MYF(MY_WME));
 
460
}
 
461
 
 
462
int delete_table_proto_file(const char *file_name)
 
463
{
 
464
  string new_path(file_name);
 
465
  string file_ext = ".dfe";
 
466
 
 
467
  new_path.append(file_ext);
 
468
  return my_delete(new_path.c_str(), MYF(0));
 
469
}
 
470
 
 
471
int drizzle_write_proto_file(const std::string file_name,
 
472
                             message::Table *table_proto)
 
473
{
 
474
  int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask);
 
475
 
 
476
  if (fd == -1)
 
477
    return errno;
 
478
 
 
479
  google::protobuf::io::ZeroCopyOutputStream* output=
 
480
    new google::protobuf::io::FileOutputStream(fd);
 
481
 
 
482
  if (table_proto->SerializeToZeroCopyStream(output) == false)
 
483
  {
 
484
    delete output;
 
485
    close(fd);
 
486
    return errno;
 
487
  }
 
488
 
 
489
  delete output;
 
490
  close(fd);
 
491
  return 0;
 
492
}
 
493
 
446
494
/*
447
495
  Create a table definition proto file and the tables
448
496
 
456
504
    create_fields       Fields to create
457
505
    keys                number of keys to create
458
506
    key_info            Keys to create
 
507
    file                Handler to use
 
508
    is_like             is true for mysql_create_like_schema_frm
459
509
 
460
510
  RETURN
461
511
    0  ok
462
512
    1  error
463
513
*/
464
514
 
465
 
bool rea_create_table(Session *session,
466
 
                      TableIdentifier &identifier,
467
 
                      message::Table &table_proto,
468
 
                      HA_CREATE_INFO *create_info,
469
 
                      List<CreateField> &create_fields,
470
 
                      uint32_t keys, KEY *key_info)
 
515
int rea_create_table(Session *session, const char *path,
 
516
                     const char *db, const char *table_name,
 
517
                     message::Table *table_proto,
 
518
                     HA_CREATE_INFO *create_info,
 
519
                     List<CreateField> &create_fields,
 
520
                     uint32_t keys, KEY *key_info)
471
521
{
472
 
  if (fill_table_proto(table_proto, identifier.getTableName(), create_fields, create_info,
473
 
                       keys, key_info))
474
 
    return false;
475
 
 
476
 
  if (plugin::StorageEngine::createTable(*session,
477
 
                                         identifier,
478
 
                                         false, table_proto))
 
522
  /* Proto will blow up unless we give a name */
 
523
  assert(table_name);
 
524
 
 
525
  if (fill_table_proto(table_proto, table_name, create_fields, create_info,
 
526
                      keys, key_info))
 
527
    return 1;
 
528
 
 
529
  string new_path(path);
 
530
  string file_ext = ".dfe";
 
531
 
 
532
  new_path.append(file_ext);
 
533
 
 
534
  int err= 0;
 
535
 
 
536
  StorageEngine* engine= ha_resolve_by_name(session,
 
537
                                            table_proto->engine().name());
 
538
  if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
 
539
    err= drizzle_write_proto_file(new_path, table_proto);
 
540
 
 
541
  if (err != 0)
479
542
  {
480
 
    return false;
 
543
    if (err == ENOENT)
 
544
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
545
    else
 
546
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,err);
 
547
 
 
548
    goto err_handler;
481
549
  }
482
550
 
483
 
  return true;
484
 
 
 
551
  if (ha_create_table(session, path, db, table_name,
 
552
                      create_info,0, table_proto))
 
553
    goto err_handler;
 
554
  return 0;
 
555
 
 
556
err_handler:
 
557
  if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
 
558
    delete_table_proto_file(path);
 
559
 
 
560
  return 1;
485
561
} /* rea_create_table */
486
 
 
487
 
} /* namespace drizzled */
488