~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/debian-changes-2010.12.06-0ubuntu4/drizzled/table_proto_write.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2011-01-04 09:31:58 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20110104093158-smhgvkfdi2y9au3i
Tags: 2011.01.07-0ubuntu1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
#include "config.h"
17
 
#include <drizzled/error.h>
18
 
#include <drizzled/session.h>
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
 
 
27
 
/* For proto */
28
 
#include <string>
29
 
#include <fstream>
30
 
#include <fcntl.h>
31
 
#include <drizzled/message/schema.pb.h>
32
 
#include <drizzled/message/table.pb.h>
33
 
#include <google/protobuf/io/zero_copy_stream.h>
34
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
35
 
#include <google/protobuf/message.h>
36
 
 
37
 
#include <drizzled/table_proto.h>
38
 
#include <drizzled/charset.h>
39
 
 
40
 
#include "drizzled/function/time/typecast.h"
41
 
 
42
 
using namespace std;
43
 
 
44
 
namespace drizzled {
45
 
 
46
 
static int fill_table_proto(message::Table &table_proto,
47
 
                            List<CreateField> &create_fields,
48
 
                            HA_CREATE_INFO *create_info,
49
 
                            uint32_t keys,
50
 
                            KeyInfo *key_info)
51
 
{
52
 
  CreateField *field_arg;
53
 
  List_iterator<CreateField> it(create_fields);
54
 
  message::Table::TableOptions *table_options= table_proto.mutable_options();
55
 
 
56
 
  if (create_fields.elements > MAX_FIELDS)
57
 
  {
58
 
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
59
 
    return(1);
60
 
  }
61
 
 
62
 
  assert(strcmp(table_proto.engine().name().c_str(),
63
 
                create_info->db_type->getName().c_str())==0);
64
 
 
65
 
  int field_number= 0;
66
 
  bool use_existing_fields= table_proto.field_size() > 0;
67
 
  while ((field_arg= it++))
68
 
  {
69
 
    message::Table::Field *attribute;
70
 
 
71
 
    /* some (one) code path for CREATE TABLE fills the proto
72
 
       out more than the others, so we already have partially
73
 
       filled out Field messages */
74
 
 
75
 
    if (use_existing_fields)
76
 
    {
77
 
      attribute= table_proto.mutable_field(field_number++);
78
 
    }
79
 
    else
80
 
    {
81
 
      /* Other code paths still have to fill out the proto */
82
 
      attribute= table_proto.add_field();
83
 
 
84
 
      if (field_arg->flags & NOT_NULL_FLAG)
85
 
      {
86
 
        attribute->mutable_constraints()->set_is_nullable(false);
87
 
      }
88
 
      else
89
 
      {
90
 
        attribute->mutable_constraints()->set_is_nullable(true);
91
 
      }
92
 
 
93
 
      if (field_arg->flags & UNSIGNED_FLAG and 
94
 
          (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
95
 
      {
96
 
        field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
97
 
        attribute->mutable_constraints()->set_is_unsigned(true);
98
 
      }
99
 
 
100
 
      attribute->set_name(field_arg->field_name);
101
 
    }
102
 
 
103
 
    assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
104
 
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
105
 
 
106
 
 
107
 
    message::Table::Field::FieldType parser_type= attribute->type();
108
 
 
109
 
    if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
110
 
    {
111
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
112
 
      return -1;
113
 
    }
114
 
 
115
 
    if (field_arg->flags & UNSIGNED_FLAG and 
116
 
       (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
117
 
    {
118
 
      message::Table::Field::FieldConstraints *constraints= attribute->mutable_constraints();
119
 
 
120
 
      field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
121
 
      constraints->set_is_unsigned(true);
122
 
 
123
 
      if (field_arg->flags & NOT_NULL_FLAG)
124
 
      {
125
 
        constraints->set_is_nullable(false);
126
 
      }
127
 
      else
128
 
      {
129
 
        constraints->set_is_nullable(true);
130
 
      }
131
 
    }
132
 
 
133
 
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
134
 
 
135
 
    switch (attribute->type()) {
136
 
    default: /* Only deal with types that need extra information */
137
 
      break;
138
 
    case message::Table::Field::DOUBLE:
139
 
      {
140
 
        /*
141
 
         * For DOUBLE, we only add a specific scale and precision iff
142
 
         * the fixed decimal point has been specified...
143
 
         */
144
 
        if (field_arg->decimals != NOT_FIXED_DEC)
145
 
        {
146
 
          message::Table::Field::NumericFieldOptions *numeric_field_options;
147
 
 
148
 
          numeric_field_options= attribute->mutable_numeric_options();
149
 
 
150
 
          numeric_field_options->set_precision(field_arg->length);
151
 
          numeric_field_options->set_scale(field_arg->decimals);
152
 
        }
153
 
      }
154
 
      break;
155
 
    case message::Table::Field::VARCHAR:
156
 
      {
157
 
        message::Table::Field::StringFieldOptions *string_field_options;
158
 
 
159
 
        string_field_options= attribute->mutable_string_options();
160
 
 
161
 
        if (! use_existing_fields || string_field_options->length()==0)
162
 
          string_field_options->set_length(field_arg->length
163
 
                                           / field_arg->charset->mbmaxlen);
164
 
        else
165
 
          assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
166
 
 
167
 
        if (! string_field_options->has_collation())
168
 
        {
169
 
          string_field_options->set_collation_id(field_arg->charset->number);
170
 
          string_field_options->set_collation(field_arg->charset->name);
171
 
        }
172
 
        break;
173
 
      }
174
 
    case message::Table::Field::DECIMAL:
175
 
      {
176
 
        message::Table::Field::NumericFieldOptions *numeric_field_options;
177
 
 
178
 
        numeric_field_options= attribute->mutable_numeric_options();
179
 
        /* This is magic, I hate magic numbers -Brian */
180
 
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
181
 
        numeric_field_options->set_scale(field_arg->decimals);
182
 
        break;
183
 
      }
184
 
    case message::Table::Field::ENUM:
185
 
      {
186
 
        message::Table::Field::EnumerationValues *enumeration_options;
187
 
 
188
 
        assert(field_arg->interval);
189
 
 
190
 
        enumeration_options= attribute->mutable_enumeration_values();
191
 
 
192
 
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
193
 
        {
194
 
          const char *src= field_arg->interval->type_names[pos];
195
 
 
196
 
          enumeration_options->add_field_value(src);
197
 
        }
198
 
        enumeration_options->set_collation_id(field_arg->charset->number);
199
 
        enumeration_options->set_collation(field_arg->charset->name);
200
 
        break;
201
 
      }
202
 
    case message::Table::Field::BLOB:
203
 
      {
204
 
        message::Table::Field::StringFieldOptions *string_field_options;
205
 
 
206
 
        string_field_options= attribute->mutable_string_options();
207
 
        string_field_options->set_collation_id(field_arg->charset->number);
208
 
        string_field_options->set_collation(field_arg->charset->name);
209
 
      }
210
 
 
211
 
      break;
212
 
    }
213
 
 
214
 
    assert (!use_existing_fields || parser_type == attribute->type());
215
 
 
216
 
#ifdef NOTDONE
217
 
    field_constraints= attribute->mutable_constraints();
218
 
    constraints->set_is_nullable(field_arg->def->null_value);
219
 
#endif
220
 
 
221
 
    if (field_arg->comment.length)
222
 
    {
223
 
      uint32_t tmp_len;
224
 
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
225
 
                                                  field_arg->comment.str,
226
 
                                                  field_arg->comment.str +
227
 
                                                  field_arg->comment.length,
228
 
                                                  COLUMN_COMMENT_MAXLEN);
229
 
 
230
 
      if (tmp_len < field_arg->comment.length)
231
 
      {
232
 
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
233
 
                 field_arg->comment.str,"COLUMN COMMENT",
234
 
                 (uint32_t) COLUMN_COMMENT_MAXLEN);
235
 
        return(1);
236
 
      }
237
 
 
238
 
      if (! use_existing_fields)
239
 
        attribute->set_comment(field_arg->comment.str);
240
 
 
241
 
      assert(strcmp(attribute->comment().c_str(), field_arg->comment.str)==0);
242
 
    }
243
 
 
244
 
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
245
 
    {
246
 
      message::Table::Field::NumericFieldOptions *field_options;
247
 
      field_options= attribute->mutable_numeric_options();
248
 
      field_options->set_is_autoincrement(true);
249
 
    }
250
 
 
251
 
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
252
 
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
253
 
    {
254
 
      message::Table::Field::FieldOptions *field_options;
255
 
      field_options= attribute->mutable_options();
256
 
      field_options->set_default_expression("CURRENT_TIMESTAMP");
257
 
    }
258
 
 
259
 
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
260
 
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
261
 
    {
262
 
      message::Table::Field::FieldOptions *field_options;
263
 
      field_options= attribute->mutable_options();
264
 
      field_options->set_update_expression("CURRENT_TIMESTAMP");
265
 
    }
266
 
 
267
 
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
268
 
    {
269
 
      message::Table::Field::FieldOptions *field_options;
270
 
      field_options= attribute->mutable_options();
271
 
 
272
 
      field_options->set_default_null(true);
273
 
    }
274
 
    if (field_arg->def)
275
 
    {
276
 
      message::Table::Field::FieldOptions *field_options;
277
 
      field_options= attribute->mutable_options();
278
 
 
279
 
      if (field_arg->def->is_null())
280
 
      {
281
 
        field_options->set_default_null(true);
282
 
      }
283
 
      else
284
 
      {
285
 
        String d;
286
 
        String *default_value= field_arg->def->val_str(&d);
287
 
 
288
 
        assert(default_value);
289
 
 
290
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
291
 
           || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
292
 
           && ((field_arg->length / field_arg->charset->mbmaxlen)
293
 
           < default_value->length()))
294
 
        {
295
 
          my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
296
 
          return 1;
297
 
        }
298
 
 
299
 
        if (field_arg->sql_type == DRIZZLE_TYPE_DATE
300
 
            || field_arg->sql_type == DRIZZLE_TYPE_DATETIME
301
 
            || field_arg->sql_type == DRIZZLE_TYPE_TIMESTAMP)
302
 
        {
303
 
          DRIZZLE_TIME ltime;
304
 
 
305
 
          if (field_arg->def->get_date(&ltime, TIME_FUZZY_DATE))
306
 
          {
307
 
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
308
 
                     default_value->c_str());
309
 
            return 1;
310
 
          }
311
 
 
312
 
          /* We now do the casting down to the appropriate type.
313
 
 
314
 
             Yes, this implicit casting is balls.
315
 
             It was previously done on reading the proto back in,
316
 
             but we really shouldn't store the bogus things in the proto,
317
 
             and instead do the casting behaviour here.
318
 
 
319
 
             the timestamp errors are taken care of elsewhere.
320
 
          */
321
 
 
322
 
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
323
 
          {
324
 
            Item *typecast= new Item_datetime_typecast(field_arg->def);
325
 
            typecast->quick_fix_field();
326
 
            typecast->val_str(default_value);
327
 
          }
328
 
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
329
 
          {
330
 
            Item *typecast= new Item_date_typecast(field_arg->def);
331
 
            typecast->quick_fix_field();
332
 
            typecast->val_str(default_value);
333
 
          }
334
 
        }
335
 
 
336
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
337
 
            && field_arg->charset==&my_charset_bin)
338
 
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
339
 
            && field_arg->charset==&my_charset_bin))
340
 
        {
341
 
          string bin_default;
342
 
          bin_default.assign(default_value->c_ptr(),
343
 
                             default_value->length());
344
 
          field_options->set_default_bin_value(bin_default);
345
 
        }
346
 
        else
347
 
        {
348
 
          field_options->set_default_value(default_value->c_ptr());
349
 
        }
350
 
      }
351
 
    }
352
 
 
353
 
    assert(field_arg->unireg_check == Field::NONE
354
 
           || field_arg->unireg_check == Field::NEXT_NUMBER
355
 
           || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
356
 
           || field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
357
 
           || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD);
358
 
 
359
 
  }
360
 
 
361
 
  assert(! use_existing_fields || (field_number == table_proto.field_size()));
362
 
 
363
 
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
364
 
    table_options->set_pack_record(true);
365
 
 
366
 
  if (table_options->has_comment() && table_options->comment().length() == 0)
367
 
    table_options->clear_comment();
368
 
 
369
 
  if (table_options->has_comment())
370
 
  {
371
 
    uint32_t tmp_len;
372
 
    tmp_len= system_charset_info->cset->charpos(system_charset_info,
373
 
                                                table_options->comment().c_str(),
374
 
                                                table_options->comment().c_str() +
375
 
                                                table_options->comment().length(),
376
 
                                                TABLE_COMMENT_MAXLEN);
377
 
 
378
 
    if (tmp_len < table_options->comment().length())
379
 
    {
380
 
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
381
 
               table_options->comment().c_str(),"Table COMMENT",
382
 
               (uint32_t) TABLE_COMMENT_MAXLEN);
383
 
      return(1);
384
 
    }
385
 
  }
386
 
 
387
 
  if (create_info->default_table_charset)
388
 
  {
389
 
    table_options->set_collation_id(
390
 
                               create_info->default_table_charset->number);
391
 
    table_options->set_collation(create_info->default_table_charset->name);
392
 
  }
393
 
 
394
 
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
395
 
    table_options->set_has_user_set_auto_increment_value(true);
396
 
  else
397
 
    table_options->set_has_user_set_auto_increment_value(false);
398
 
 
399
 
  if (create_info->auto_increment_value)
400
 
    table_options->set_auto_increment_value(create_info->auto_increment_value);
401
 
 
402
 
  for (uint32_t i= 0; i < keys; i++)
403
 
  {
404
 
    message::Table::Index *idx;
405
 
 
406
 
    idx= table_proto.add_indexes();
407
 
 
408
 
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
409
 
           (key_info[i].comment.length > 0));
410
 
 
411
 
    idx->set_name(key_info[i].name);
412
 
 
413
 
    idx->set_key_length(key_info[i].key_length);
414
 
 
415
 
    if (is_primary_key_name(key_info[i].name))
416
 
      idx->set_is_primary(true);
417
 
    else
418
 
      idx->set_is_primary(false);
419
 
 
420
 
    switch(key_info[i].algorithm)
421
 
    {
422
 
    case HA_KEY_ALG_HASH:
423
 
      idx->set_type(message::Table::Index::HASH);
424
 
      break;
425
 
 
426
 
    case HA_KEY_ALG_BTREE:
427
 
      idx->set_type(message::Table::Index::BTREE);
428
 
      break;
429
 
 
430
 
    case HA_KEY_ALG_UNDEF:
431
 
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
432
 
      break;
433
 
 
434
 
    default:
435
 
      abort(); /* Somebody's brain broke. haven't added index type to proto */
436
 
    }
437
 
 
438
 
    if (key_info[i].flags & HA_NOSAME)
439
 
      idx->set_is_unique(true);
440
 
    else
441
 
      idx->set_is_unique(false);
442
 
 
443
 
    message::Table::Index::Options *index_options= idx->mutable_options();
444
 
 
445
 
    if (key_info[i].flags & HA_USES_BLOCK_SIZE)
446
 
      index_options->set_key_block_size(key_info[i].block_size);
447
 
 
448
 
    if (key_info[i].flags & HA_PACK_KEY)
449
 
      index_options->set_pack_key(true);
450
 
 
451
 
    if (key_info[i].flags & HA_BINARY_PACK_KEY)
452
 
      index_options->set_binary_pack_key(true);
453
 
 
454
 
    if (key_info[i].flags & HA_VAR_LENGTH_PART)
455
 
      index_options->set_var_length_key(true);
456
 
 
457
 
    if (key_info[i].flags & HA_NULL_PART_KEY)
458
 
      index_options->set_null_part_key(true);
459
 
 
460
 
    if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
461
 
      index_options->set_has_partial_segments(true);
462
 
 
463
 
    if (key_info[i].flags & HA_GENERATED_KEY)
464
 
      index_options->set_auto_generated_key(true);
465
 
 
466
 
    if (key_info[i].flags & HA_USES_COMMENT)
467
 
    {
468
 
      uint32_t tmp_len;
469
 
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
470
 
                                                  key_info[i].comment.str,
471
 
                                                  key_info[i].comment.str +
472
 
                                                  key_info[i].comment.length,
473
 
                                                  TABLE_COMMENT_MAXLEN);
474
 
 
475
 
      if (tmp_len < key_info[i].comment.length)
476
 
      {
477
 
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
478
 
                 key_info[i].comment.str,"Index COMMENT",
479
 
                 (uint32_t) TABLE_COMMENT_MAXLEN);
480
 
        return(1);
481
 
      }
482
 
 
483
 
      idx->set_comment(key_info[i].comment.str);
484
 
    }
485
 
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
486
 
                                               HA_USES_BLOCK_SIZE | 
487
 
                                               HA_BINARY_PACK_KEY |
488
 
                                               HA_VAR_LENGTH_PART |
489
 
                                               HA_NULL_PART_KEY | 
490
 
                                               HA_KEY_HAS_PART_KEY_SEG |
491
 
                                               HA_GENERATED_KEY |
492
 
                                               HA_USES_COMMENT);
493
 
    if (key_info[i].flags & ~unknown_index_flag)
494
 
      abort(); // Invalid (unknown) index flag.
495
 
 
496
 
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
497
 
    {
498
 
      message::Table::Index::IndexPart *idxpart;
499
 
      const int fieldnr= key_info[i].key_part[j].fieldnr;
500
 
      int mbmaxlen= 1;
501
 
 
502
 
      idxpart= idx->add_index_part();
503
 
 
504
 
      idxpart->set_fieldnr(fieldnr);
505
 
 
506
 
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
507
 
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
508
 
      {
509
 
        uint32_t collation_id;
510
 
 
511
 
        if (table_proto.field(fieldnr).string_options().has_collation_id())
512
 
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
513
 
        else
514
 
          collation_id= table_proto.options().collation_id();
515
 
 
516
 
        const CHARSET_INFO *cs= get_charset(collation_id);
517
 
 
518
 
        mbmaxlen= cs->mbmaxlen;
519
 
      }
520
 
 
521
 
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
522
 
    }
523
 
  }
524
 
 
525
 
  if (not table_proto.IsInitialized())
526
 
  {
527
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
528
 
    return 1;
529
 
  }
530
 
 
531
 
  /*
532
 
    Here we test to see if we can validate the Table Message before we continue. 
533
 
    We do this by serializing the protobuffer.
534
 
  */
535
 
  {
536
 
    string tmp_string;
537
 
 
538
 
    try {
539
 
      table_proto.SerializeToString(&tmp_string);
540
 
    }
541
 
 
542
 
    catch (...)
543
 
    {
544
 
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
545
 
               table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
546
 
 
547
 
      return 1;
548
 
    }
549
 
  }
550
 
 
551
 
  return 0;
552
 
}
553
 
 
554
 
/*
555
 
  Create a table definition proto file and the tables
556
 
 
557
 
  SYNOPSIS
558
 
    rea_create_table()
559
 
    session                     Thread handler
560
 
    path                Name of file (including database, without .frm)
561
 
    db                  Data base name
562
 
    table_name          Table name
563
 
    create_info         create info parameters
564
 
    create_fields       Fields to create
565
 
    keys                number of keys to create
566
 
    key_info            Keys to create
567
 
 
568
 
  RETURN
569
 
    0  ok
570
 
    1  error
571
 
*/
572
 
 
573
 
bool rea_create_table(Session *session,
574
 
                      const TableIdentifier &identifier,
575
 
                      message::Table &table_proto,
576
 
                      HA_CREATE_INFO *create_info,
577
 
                      List<CreateField> &create_fields,
578
 
                      uint32_t keys, KeyInfo *key_info)
579
 
{
580
 
  assert(table_proto.has_name());
581
 
  if (fill_table_proto(table_proto, create_fields, create_info,
582
 
                       keys, key_info))
583
 
    return false;
584
 
 
585
 
  assert(table_proto.name() == identifier.getTableName());
586
 
 
587
 
  if (plugin::StorageEngine::createTable(*session,
588
 
                                         identifier,
589
 
                                         table_proto))
590
 
  {
591
 
    return false;
592
 
  }
593
 
 
594
 
  return true;
595
 
 
596
 
} /* rea_create_table */
597
 
 
598
 
} /* namespace drizzled */
599