~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_proto_write.cc

  • Committer: Brian Aker
  • Date: 2010-03-31 19:14:14 UTC
  • Revision ID: brian@gaz-20100331191414-9yv44mmpvf0tb7l1
Updated to use show schemas specific table.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
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 */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "config.h"
17
17
#include <drizzled/error.h>
32
32
#include <drizzled/message/table.pb.h>
33
33
#include <google/protobuf/io/zero_copy_stream.h>
34
34
#include <google/protobuf/io/zero_copy_stream_impl.h>
35
 
#include <google/protobuf/message.h>
36
35
 
37
36
#include <drizzled/table_proto.h>
38
 
#include <drizzled/charset.h>
39
 
 
40
 
#include "drizzled/function/time/typecast.h"
41
37
 
42
38
using namespace std;
43
39
 
44
40
namespace drizzled {
45
41
 
46
42
static int fill_table_proto(message::Table &table_proto,
 
43
                            const std::string &table_name,
47
44
                            List<CreateField> &create_fields,
48
45
                            HA_CREATE_INFO *create_info,
49
46
                            uint32_t keys,
50
 
                            KeyInfo *key_info)
 
47
                            KEY *key_info)
51
48
{
52
49
  CreateField *field_arg;
53
50
  List_iterator<CreateField> it(create_fields);
62
59
  assert(strcmp(table_proto.engine().name().c_str(),
63
60
                create_info->db_type->getName().c_str())==0);
64
61
 
 
62
  assert(table_proto.name() == table_name);
 
63
 
65
64
  int field_number= 0;
66
65
  bool use_existing_fields= table_proto.field_size() > 0;
67
66
  while ((field_arg= it++))
96
95
 
97
96
    message::Table::Field::FieldType parser_type= attribute->type();
98
97
 
99
 
    if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
100
 
    {
101
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
102
 
      return -1;
103
 
    }
104
 
 
105
98
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
106
99
 
107
100
    switch (attribute->type()) {
190
183
    constraints->set_is_nullable(field_arg->def->null_value);
191
184
#endif
192
185
 
 
186
    switch(field_arg->column_format())
 
187
    {
 
188
    case COLUMN_FORMAT_TYPE_NOT_USED:
 
189
      break;
 
190
    case COLUMN_FORMAT_TYPE_DEFAULT:
 
191
      attribute->set_format(message::Table::Field::DefaultFormat);
 
192
      break;
 
193
    case COLUMN_FORMAT_TYPE_FIXED:
 
194
      attribute->set_format(message::Table::Field::FixedFormat);
 
195
      break;
 
196
    case COLUMN_FORMAT_TYPE_DYNAMIC:
 
197
      attribute->set_format(message::Table::Field::DynamicFormat);
 
198
      break;
 
199
    default:
 
200
      assert(0); /* Tell us, since this shouldn't happend */
 
201
    }
 
202
 
193
203
    if (field_arg->comment.length)
194
204
    {
195
205
      uint32_t tmp_len;
225
235
    {
226
236
      message::Table::Field::FieldOptions *field_options;
227
237
      field_options= attribute->mutable_options();
228
 
      field_options->set_default_expression("CURRENT_TIMESTAMP");
 
238
      field_options->set_default_value("NOW()");
229
239
    }
230
240
 
231
241
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
233
243
    {
234
244
      message::Table::Field::FieldOptions *field_options;
235
245
      field_options= attribute->mutable_options();
236
 
      field_options->set_update_expression("CURRENT_TIMESTAMP");
 
246
      field_options->set_update_value("NOW()");
237
247
    }
238
248
 
239
249
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
268
278
          return 1;
269
279
        }
270
280
 
271
 
        if (field_arg->sql_type == DRIZZLE_TYPE_DATE
272
 
            || field_arg->sql_type == DRIZZLE_TYPE_DATETIME
273
 
            || field_arg->sql_type == DRIZZLE_TYPE_TIMESTAMP)
274
 
        {
275
 
          DRIZZLE_TIME ltime;
276
 
 
277
 
          if (field_arg->def->get_date(&ltime, TIME_FUZZY_DATE))
278
 
          {
279
 
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
280
 
                     default_value->c_str());
281
 
            return 1;
282
 
          }
283
 
 
284
 
          /* We now do the casting down to the appropriate type.
285
 
 
286
 
             Yes, this implicit casting is balls.
287
 
             It was previously done on reading the proto back in,
288
 
             but we really shouldn't store the bogus things in the proto,
289
 
             and instead do the casting behaviour here.
290
 
 
291
 
             the timestamp errors are taken care of elsewhere.
292
 
          */
293
 
 
294
 
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
295
 
          {
296
 
            Item *typecast= new Item_datetime_typecast(field_arg->def);
297
 
            typecast->quick_fix_field();
298
 
            typecast->val_str(default_value);
299
 
          }
300
 
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
301
 
          {
302
 
            Item *typecast= new Item_date_typecast(field_arg->def);
303
 
            typecast->quick_fix_field();
304
 
            typecast->val_str(default_value);
305
 
          }
306
 
        }
307
 
 
308
281
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
309
282
            && field_arg->charset==&my_charset_bin)
310
283
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
335
308
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
336
309
    table_options->set_pack_record(true);
337
310
 
338
 
  if (table_options->has_comment() && table_options->comment().length() == 0)
339
 
    table_options->clear_comment();
340
 
 
341
311
  if (table_options->has_comment())
342
312
  {
343
313
    uint32_t tmp_len;
363
333
    table_options->set_collation(create_info->default_table_charset->name);
364
334
  }
365
335
 
366
 
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
367
 
    table_options->set_has_user_set_auto_increment_value(true);
368
 
  else
369
 
    table_options->set_has_user_set_auto_increment_value(false);
370
 
 
371
336
  if (create_info->auto_increment_value)
372
337
    table_options->set_auto_increment_value(create_info->auto_increment_value);
373
338
 
412
377
    else
413
378
      idx->set_is_unique(false);
414
379
 
415
 
    message::Table::Index::Options *index_options= idx->mutable_options();
 
380
    message::Table::Index::IndexOptions *index_options= idx->mutable_options();
416
381
 
417
382
    if (key_info[i].flags & HA_USES_BLOCK_SIZE)
418
383
      index_options->set_key_block_size(key_info[i].block_size);
454
419
 
455
420
      idx->set_comment(key_info[i].comment.str);
456
421
    }
457
 
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
458
 
                                               HA_USES_BLOCK_SIZE | 
459
 
                                               HA_BINARY_PACK_KEY |
460
 
                                               HA_VAR_LENGTH_PART |
461
 
                                               HA_NULL_PART_KEY | 
462
 
                                               HA_KEY_HAS_PART_KEY_SEG |
463
 
                                               HA_GENERATED_KEY |
464
 
                                               HA_USES_COMMENT);
465
 
    if (key_info[i].flags & ~unknown_index_flag)
 
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))
466
426
      abort(); // Invalid (unknown) index flag.
467
427
 
468
428
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
469
429
    {
470
430
      message::Table::Index::IndexPart *idxpart;
471
 
      const int fieldnr= key_info[i].key_part[j].fieldnr;
472
 
      int mbmaxlen= 1;
473
431
 
474
432
      idxpart= idx->add_index_part();
475
433
 
476
 
      idxpart->set_fieldnr(fieldnr);
477
 
 
478
 
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
479
 
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
480
 
      {
481
 
        uint32_t collation_id;
482
 
 
483
 
        if (table_proto.field(fieldnr).string_options().has_collation_id())
484
 
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
485
 
        else
486
 
          collation_id= table_proto.options().collation_id();
487
 
 
488
 
        const CHARSET_INFO *cs= get_charset(collation_id);
489
 
 
490
 
        mbmaxlen= cs->mbmaxlen;
491
 
      }
492
 
 
493
 
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
494
 
    }
495
 
  }
496
 
 
497
 
  if (not table_proto.IsInitialized())
498
 
  {
499
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
500
 
    return 1;
501
 
  }
502
 
 
503
 
  /*
504
 
    Here we test to see if we can validate the Table Message before we continue. 
505
 
    We do this by serializing the protobuffer.
506
 
  */
507
 
  {
508
 
    string tmp_string;
509
 
 
510
 
    try {
511
 
      table_proto.SerializeToString(&tmp_string);
512
 
    }
513
 
 
514
 
    catch (...)
515
 
    {
516
 
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
517
 
               table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
518
 
 
519
 
      return 1;
 
434
      idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
 
435
 
 
436
      idxpart->set_compare_length(key_info[i].key_part[j].length);
 
437
 
 
438
      idxpart->set_key_type(key_info[i].key_part[j].key_type);
 
439
 
520
440
    }
521
441
  }
522
442
 
543
463
*/
544
464
 
545
465
bool rea_create_table(Session *session,
546
 
                      const TableIdentifier &identifier,
 
466
                      TableIdentifier &identifier,
547
467
                      message::Table &table_proto,
548
468
                      HA_CREATE_INFO *create_info,
549
469
                      List<CreateField> &create_fields,
550
 
                      uint32_t keys, KeyInfo *key_info)
 
470
                      uint32_t keys, KEY *key_info)
551
471
{
552
 
  assert(table_proto.has_name());
553
 
  if (fill_table_proto(table_proto, create_fields, create_info,
 
472
  if (fill_table_proto(table_proto, identifier.getTableName(), create_fields, create_info,
554
473
                       keys, key_info))
555
474
    return false;
556
475
 
557
 
  assert(table_proto.name() == identifier.getTableName());
558
 
 
559
476
  if (plugin::StorageEngine::createTable(*session,
560
477
                                         identifier,
561
 
                                         table_proto))
 
478
                                         false, table_proto))
562
479
  {
563
480
    return false;
564
481
  }