~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_proto_write.cc

  • Committer: Brian Aker
  • Date: 2010-06-02 17:48:07 UTC
  • mto: (1578.6.10 explain-drizzle)
  • mto: This revision was merged to the branch mainline in revision 1589.
  • Revision ID: brian@gir-2.local-20100602174807-9unmrwp18ewkwol5
Modify merge-buffer to use std::vector in one location (just curious to see
if this shows up on benchmarks).

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
 
#include <config.h>
 
16
#include "config.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/plugin/storage_engine.h>
25
 
 
26
 
#include <drizzled/internal/my_sys.h>
27
 
#include <drizzled/typelib.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
 
28
26
 
29
27
/* For proto */
30
28
#include <string>
34
32
#include <drizzled/message/table.pb.h>
35
33
#include <google/protobuf/io/zero_copy_stream.h>
36
34
#include <google/protobuf/io/zero_copy_stream_impl.h>
37
 
#include <google/protobuf/message.h>
38
35
 
39
36
#include <drizzled/table_proto.h>
40
 
#include <drizzled/charset.h>
41
 
 
42
 
#include <drizzled/function/time/typecast.h>
43
37
 
44
38
using namespace std;
45
39
 
46
40
namespace drizzled {
47
41
 
48
 
bool fill_table_proto(message::Table &table_proto,
49
 
                      List<CreateField> &create_fields,
50
 
                      HA_CREATE_INFO *create_info,
51
 
                      uint32_t keys,
52
 
                      KeyInfo *key_info)
 
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
                            KeyInfo *key_info)
53
48
{
54
49
  CreateField *field_arg;
55
 
  List<CreateField>::iterator it(create_fields.begin());
 
50
  List_iterator<CreateField> it(create_fields);
56
51
  message::Table::TableOptions *table_options= table_proto.mutable_options();
57
52
 
58
53
  if (create_fields.elements > MAX_FIELDS)
59
54
  {
60
55
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
61
 
    return true;
 
56
    return(1);
62
57
  }
63
58
 
64
59
  assert(strcmp(table_proto.engine().name().c_str(),
65
60
                create_info->db_type->getName().c_str())==0);
66
61
 
 
62
  assert(table_proto.name() == table_name);
 
63
 
67
64
  int field_number= 0;
68
65
  bool use_existing_fields= table_proto.field_size() > 0;
69
66
  while ((field_arg= it++))
75
72
       filled out Field messages */
76
73
 
77
74
    if (use_existing_fields)
78
 
    {
79
75
      attribute= table_proto.mutable_field(field_number++);
80
 
    }
81
76
    else
82
77
    {
83
78
      /* Other code paths still have to fill out the proto */
85
80
 
86
81
      if (field_arg->flags & NOT_NULL_FLAG)
87
82
      {
88
 
        attribute->mutable_constraints()->set_is_notnull(true);
89
 
      }
 
83
        message::Table::Field::FieldConstraints *constraints;
90
84
 
91
 
      if (field_arg->flags & UNSIGNED_FLAG and 
92
 
          (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
93
 
      {
94
 
        field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
95
 
        attribute->mutable_constraints()->set_is_unsigned(true);
 
85
        constraints= attribute->mutable_constraints();
 
86
        constraints->set_is_nullable(false);
96
87
      }
97
88
 
98
89
      attribute->set_name(field_arg->field_name);
99
90
    }
100
91
 
101
 
    assert(((field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_notnull());
 
92
    assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
102
93
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
103
94
 
104
95
 
105
96
    message::Table::Field::FieldType parser_type= attribute->type();
106
97
 
107
 
    if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
108
 
    {
109
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
110
 
      return true;
111
 
    }
112
 
 
113
 
    if (field_arg->flags & UNSIGNED_FLAG and 
114
 
       (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
115
 
    {
116
 
      message::Table::Field::FieldConstraints *constraints= attribute->mutable_constraints();
117
 
 
118
 
      field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
119
 
      constraints->set_is_unsigned(true);
120
 
    }
121
 
 
122
98
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
123
99
 
124
100
    switch (attribute->type()) {
125
 
    case message::Table::Field::BIGINT:
126
 
    case message::Table::Field::INTEGER:
127
 
    case message::Table::Field::DATE:
128
 
    case message::Table::Field::DATETIME:
129
 
    case message::Table::Field::UUID:
130
 
    case message::Table::Field::TIME:
131
 
    case message::Table::Field::BOOLEAN:
 
101
    default: /* Only deal with types that need extra information */
132
102
      break;
133
103
    case message::Table::Field::DOUBLE:
134
104
      {
194
164
        enumeration_options->set_collation(field_arg->charset->name);
195
165
        break;
196
166
      }
197
 
 
198
167
    case message::Table::Field::BLOB:
199
168
      {
200
169
        message::Table::Field::StringFieldOptions *string_field_options;
205
174
      }
206
175
 
207
176
      break;
208
 
 
209
 
    case message::Table::Field::EPOCH:
210
 
      {
211
 
        if (field_arg->sql_type == DRIZZLE_TYPE_MICROTIME)
212
 
          attribute->mutable_time_options()->set_microseconds(true);
213
 
      }
214
 
 
215
 
      break;
216
177
    }
217
178
 
218
179
    assert (!use_existing_fields || parser_type == attribute->type());
236
197
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
237
198
                 field_arg->comment.str,"COLUMN COMMENT",
238
199
                 (uint32_t) COLUMN_COMMENT_MAXLEN);
239
 
        return true;
 
200
        return(1);
240
201
      }
241
202
 
242
203
      if (! use_existing_fields)
257
218
    {
258
219
      message::Table::Field::FieldOptions *field_options;
259
220
      field_options= attribute->mutable_options();
260
 
      field_options->set_default_expression("CURRENT_TIMESTAMP");
 
221
      field_options->set_default_value("NOW()");
261
222
    }
262
223
 
263
224
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
265
226
    {
266
227
      message::Table::Field::FieldOptions *field_options;
267
228
      field_options= attribute->mutable_options();
268
 
      field_options->set_update_expression("CURRENT_TIMESTAMP");
 
229
      field_options->set_update_value("NOW()");
269
230
    }
270
231
 
271
 
    if (field_arg->def == NULL  && not attribute->constraints().is_notnull())
 
232
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
272
233
    {
273
234
      message::Table::Field::FieldOptions *field_options;
274
235
      field_options= attribute->mutable_options();
297
258
           < default_value->length()))
298
259
        {
299
260
          my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
300
 
          return true;
 
261
          return 1;
301
262
        }
302
263
 
303
 
        if (field::isDateTime(field_arg->sql_type))
304
 
        {
305
 
          type::Time ltime;
306
 
 
307
 
          if (field_arg->def->get_date(ltime, TIME_FUZZY_DATE))
308
 
          {
309
 
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
310
 
                     default_value->c_str());
311
 
            return true;
312
 
          }
313
 
 
314
 
          /* We now do the casting down to the appropriate type.
315
 
 
316
 
             Yes, this implicit casting is balls.
317
 
             It was previously done on reading the proto back in,
318
 
             but we really shouldn't store the bogus things in the proto,
319
 
             and instead do the casting behaviour here.
320
 
 
321
 
             the timestamp errors are taken care of elsewhere.
322
 
          */
323
 
 
324
 
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
325
 
          {
326
 
            Item *typecast= new Item_datetime_typecast(field_arg->def);
327
 
            typecast->quick_fix_field();
328
 
            typecast->val_str(default_value);
329
 
          }
330
 
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
331
 
          {
332
 
            Item *typecast= new Item_date_typecast(field_arg->def);
333
 
            typecast->quick_fix_field();
334
 
            typecast->val_str(default_value);
335
 
          }
336
 
        }
337
 
 
338
264
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
339
265
            && field_arg->charset==&my_charset_bin)
340
266
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
365
291
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
366
292
    table_options->set_pack_record(true);
367
293
 
368
 
  if (table_options->has_comment() && table_options->comment().length() == 0)
369
 
    table_options->clear_comment();
370
 
 
371
294
  if (table_options->has_comment())
372
295
  {
373
296
    uint32_t tmp_len;
382
305
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
383
306
               table_options->comment().c_str(),"Table COMMENT",
384
307
               (uint32_t) TABLE_COMMENT_MAXLEN);
385
 
      return true;
 
308
      return(1);
386
309
    }
387
310
  }
388
311
 
389
312
  if (create_info->default_table_charset)
390
313
  {
391
 
    table_options->set_collation_id(create_info->default_table_charset->number);
 
314
    table_options->set_collation_id(
 
315
                               create_info->default_table_charset->number);
392
316
    table_options->set_collation(create_info->default_table_charset->name);
393
317
  }
394
318
 
395
 
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
396
 
    table_options->set_has_user_set_auto_increment_value(true);
397
 
  else
398
 
    table_options->set_has_user_set_auto_increment_value(false);
399
 
 
400
319
  if (create_info->auto_increment_value)
401
320
    table_options->set_auto_increment_value(create_info->auto_increment_value);
402
321
 
478
397
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
479
398
                 key_info[i].comment.str,"Index COMMENT",
480
399
                 (uint32_t) TABLE_COMMENT_MAXLEN);
481
 
        return true;
 
400
        return(1);
482
401
      }
483
402
 
484
403
      idx->set_comment(key_info[i].comment.str);
485
404
    }
486
 
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
487
 
                                               HA_USES_BLOCK_SIZE | 
488
 
                                               HA_BINARY_PACK_KEY |
489
 
                                               HA_VAR_LENGTH_PART |
490
 
                                               HA_NULL_PART_KEY | 
491
 
                                               HA_KEY_HAS_PART_KEY_SEG |
492
 
                                               HA_GENERATED_KEY |
493
 
                                               HA_USES_COMMENT);
494
 
    if (key_info[i].flags & ~unknown_index_flag)
 
405
    if (key_info[i].flags & 
 
406
        ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | 
 
407
          HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | 
 
408
          HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
495
409
      abort(); // Invalid (unknown) index flag.
496
410
 
497
411
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
498
412
    {
499
413
      message::Table::Index::IndexPart *idxpart;
500
 
      const int fieldnr= key_info[i].key_part[j].fieldnr;
501
 
      int mbmaxlen= 1;
502
414
 
503
415
      idxpart= idx->add_index_part();
504
416
 
505
 
      idxpart->set_fieldnr(fieldnr);
506
 
 
507
 
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
508
 
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
509
 
      {
510
 
        uint32_t collation_id;
511
 
 
512
 
        if (table_proto.field(fieldnr).string_options().has_collation_id())
513
 
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
514
 
        else
515
 
          collation_id= table_proto.options().collation_id();
516
 
 
517
 
        const CHARSET_INFO *cs= get_charset(collation_id);
518
 
 
519
 
        mbmaxlen= cs->mbmaxlen;
520
 
      }
521
 
 
522
 
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
523
 
    }
524
 
  }
525
 
 
526
 
  if (not table_proto.IsInitialized())
527
 
  {
528
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
529
 
             table_proto.name().c_str(),
530
 
             table_proto.InitializationErrorString().c_str());
531
 
 
532
 
    return true;
533
 
  }
534
 
 
535
 
  /*
536
 
    Here we test to see if we can validate the Table Message before we continue. 
537
 
    We do this by serializing the protobuffer.
538
 
  */
539
 
  {
540
 
    string tmp_string;
541
 
 
542
 
    try {
543
 
      table_proto.SerializeToString(&tmp_string);
544
 
    }
545
 
 
546
 
    catch (...)
547
 
    {
548
 
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
549
 
               table_proto.name().c_str(),
550
 
               table_proto.InitializationErrorString().c_str());
551
 
 
552
 
      return true;
553
 
    }
554
 
  }
555
 
 
556
 
  return false;
 
417
      idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
 
418
 
 
419
      idxpart->set_compare_length(key_info[i].key_part[j].length);
 
420
    }
 
421
  }
 
422
 
 
423
  return 0;
557
424
}
558
425
 
559
426
/*
576
443
*/
577
444
 
578
445
bool rea_create_table(Session *session,
579
 
                      const identifier::Table &identifier,
 
446
                      TableIdentifier &identifier,
580
447
                      message::Table &table_proto,
581
448
                      HA_CREATE_INFO *create_info,
582
449
                      List<CreateField> &create_fields,
583
450
                      uint32_t keys, KeyInfo *key_info)
584
451
{
585
 
  assert(table_proto.has_name());
586
 
  if (fill_table_proto(table_proto, create_fields, create_info,
 
452
  if (fill_table_proto(table_proto, identifier.getTableName(), create_fields, create_info,
587
453
                       keys, key_info))
588
 
  {
589
454
    return false;
590
 
  }
591
 
 
592
 
  assert(table_proto.name() == identifier.getTableName());
593
 
 
594
 
  if (not plugin::StorageEngine::createTable(*session,
595
 
                                             identifier,
596
 
                                             table_proto))
 
455
 
 
456
  if (plugin::StorageEngine::createTable(*session,
 
457
                                         identifier,
 
458
                                         table_proto))
597
459
  {
598
460
    return false;
599
461
  }