~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_proto_write.cc

  • Committer: Monty Taylor
  • Date: 2010-07-19 05:06:59 UTC
  • mto: (1662.1.2 rollup)
  • mto: This revision was merged to the branch mainline in revision 1663.
  • Revision ID: mordred@inaugust.com-20100719050659-if3thz0k66m1jkaf
Backed out two bits that snuck in to the merge.

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>
37
35
#include <google/protobuf/message.h>
38
36
 
39
37
#include <drizzled/table_proto.h>
40
 
#include <drizzled/charset.h>
41
 
 
42
 
#include <drizzled/function/time/typecast.h>
43
38
 
44
39
using namespace std;
45
40
 
46
41
namespace drizzled {
47
42
 
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)
 
43
static int fill_table_proto(message::Table &table_proto,
 
44
                            const std::string &table_name,
 
45
                            List<CreateField> &create_fields,
 
46
                            HA_CREATE_INFO *create_info,
 
47
                            uint32_t keys,
 
48
                            KeyInfo *key_info)
53
49
{
54
50
  CreateField *field_arg;
55
 
  List<CreateField>::iterator it(create_fields.begin());
 
51
  List_iterator<CreateField> it(create_fields);
56
52
  message::Table::TableOptions *table_options= table_proto.mutable_options();
57
53
 
58
54
  if (create_fields.elements > MAX_FIELDS)
59
55
  {
60
56
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
61
 
    return true;
 
57
    return(1);
62
58
  }
63
59
 
64
60
  assert(strcmp(table_proto.engine().name().c_str(),
65
61
                create_info->db_type->getName().c_str())==0);
66
62
 
 
63
  assert(table_proto.name() == table_name);
 
64
 
67
65
  int field_number= 0;
68
66
  bool use_existing_fields= table_proto.field_size() > 0;
69
67
  while ((field_arg= it++))
75
73
       filled out Field messages */
76
74
 
77
75
    if (use_existing_fields)
78
 
    {
79
76
      attribute= table_proto.mutable_field(field_number++);
80
 
    }
81
77
    else
82
78
    {
83
79
      /* Other code paths still have to fill out the proto */
85
81
 
86
82
      if (field_arg->flags & NOT_NULL_FLAG)
87
83
      {
88
 
        attribute->mutable_constraints()->set_is_notnull(true);
89
 
      }
 
84
        message::Table::Field::FieldConstraints *constraints;
90
85
 
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);
 
86
        constraints= attribute->mutable_constraints();
 
87
        constraints->set_is_nullable(false);
96
88
      }
97
89
 
98
90
      attribute->set_name(field_arg->field_name);
99
91
    }
100
92
 
101
 
    assert(((field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_notnull());
 
93
    assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
102
94
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
103
95
 
104
96
 
105
97
    message::Table::Field::FieldType parser_type= attribute->type();
106
98
 
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
99
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
123
100
 
124
101
    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:
 
102
    default: /* Only deal with types that need extra information */
132
103
      break;
133
104
    case message::Table::Field::DOUBLE:
134
105
      {
194
165
        enumeration_options->set_collation(field_arg->charset->name);
195
166
        break;
196
167
      }
197
 
 
198
168
    case message::Table::Field::BLOB:
199
169
      {
200
170
        message::Table::Field::StringFieldOptions *string_field_options;
205
175
      }
206
176
 
207
177
      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
178
    }
217
179
 
218
180
    assert (!use_existing_fields || parser_type == attribute->type());
236
198
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
237
199
                 field_arg->comment.str,"COLUMN COMMENT",
238
200
                 (uint32_t) COLUMN_COMMENT_MAXLEN);
239
 
        return true;
 
201
        return(1);
240
202
      }
241
203
 
242
204
      if (! use_existing_fields)
257
219
    {
258
220
      message::Table::Field::FieldOptions *field_options;
259
221
      field_options= attribute->mutable_options();
260
 
      field_options->set_default_expression("CURRENT_TIMESTAMP");
 
222
      field_options->set_default_value("NOW()");
261
223
    }
262
224
 
263
225
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
265
227
    {
266
228
      message::Table::Field::FieldOptions *field_options;
267
229
      field_options= attribute->mutable_options();
268
 
      field_options->set_update_expression("CURRENT_TIMESTAMP");
 
230
      field_options->set_update_value("NOW()");
269
231
    }
270
232
 
271
 
    if (field_arg->def == NULL  && not attribute->constraints().is_notnull())
 
233
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
272
234
    {
273
235
      message::Table::Field::FieldOptions *field_options;
274
236
      field_options= attribute->mutable_options();
297
259
           < default_value->length()))
298
260
        {
299
261
          my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
300
 
          return true;
 
262
          return 1;
301
263
        }
302
264
 
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
265
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
339
266
            && field_arg->charset==&my_charset_bin)
340
267
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
365
292
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
366
293
    table_options->set_pack_record(true);
367
294
 
368
 
  if (table_options->has_comment() && table_options->comment().length() == 0)
369
 
    table_options->clear_comment();
370
 
 
371
295
  if (table_options->has_comment())
372
296
  {
373
297
    uint32_t tmp_len;
382
306
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
383
307
               table_options->comment().c_str(),"Table COMMENT",
384
308
               (uint32_t) TABLE_COMMENT_MAXLEN);
385
 
      return true;
 
309
      return(1);
386
310
    }
387
311
  }
388
312
 
389
313
  if (create_info->default_table_charset)
390
314
  {
391
 
    table_options->set_collation_id(create_info->default_table_charset->number);
 
315
    table_options->set_collation_id(
 
316
                               create_info->default_table_charset->number);
392
317
    table_options->set_collation(create_info->default_table_charset->name);
393
318
  }
394
319
 
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
320
  if (create_info->auto_increment_value)
401
321
    table_options->set_auto_increment_value(create_info->auto_increment_value);
402
322
 
478
398
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
479
399
                 key_info[i].comment.str,"Index COMMENT",
480
400
                 (uint32_t) TABLE_COMMENT_MAXLEN);
481
 
        return true;
 
401
        return(1);
482
402
      }
483
403
 
484
404
      idx->set_comment(key_info[i].comment.str);
485
405
    }
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)
 
406
    if (key_info[i].flags & 
 
407
        ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | 
 
408
          HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | 
 
409
          HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
495
410
      abort(); // Invalid (unknown) index flag.
496
411
 
497
412
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
498
413
    {
499
414
      message::Table::Index::IndexPart *idxpart;
500
 
      const int fieldnr= key_info[i].key_part[j].fieldnr;
501
 
      int mbmaxlen= 1;
502
415
 
503
416
      idxpart= idx->add_index_part();
504
417
 
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);
 
418
      idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
 
419
 
 
420
      idxpart->set_compare_length(key_info[i].key_part[j].length);
523
421
    }
524
422
  }
525
423
 
526
424
  if (not table_proto.IsInitialized())
527
425
  {
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;
 
426
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
 
427
    return 1;
533
428
  }
534
429
 
535
430
  /*
546
441
    catch (...)
547
442
    {
548
443
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
549
 
               table_proto.name().c_str(),
550
 
               table_proto.InitializationErrorString().c_str());
 
444
               table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
551
445
 
552
 
      return true;
 
446
      return 1;
553
447
    }
554
448
  }
555
449
 
556
 
  return false;
 
450
  return 0;
557
451
}
558
452
 
559
453
/*
576
470
*/
577
471
 
578
472
bool rea_create_table(Session *session,
579
 
                      const identifier::Table &identifier,
 
473
                      TableIdentifier &identifier,
580
474
                      message::Table &table_proto,
581
475
                      HA_CREATE_INFO *create_info,
582
476
                      List<CreateField> &create_fields,
583
477
                      uint32_t keys, KeyInfo *key_info)
584
478
{
585
 
  assert(table_proto.has_name());
586
 
  if (fill_table_proto(table_proto, create_fields, create_info,
 
479
  if (fill_table_proto(table_proto, identifier.getTableName(), create_fields, create_info,
587
480
                       keys, key_info))
588
 
  {
589
481
    return false;
590
 
  }
591
 
 
592
 
  assert(table_proto.name() == identifier.getTableName());
593
 
 
594
 
  if (not plugin::StorageEngine::createTable(*session,
595
 
                                             identifier,
596
 
                                             table_proto))
 
482
 
 
483
  if (plugin::StorageEngine::createTable(*session,
 
484
                                         identifier,
 
485
                                         table_proto))
597
486
  {
598
487
    return false;
599
488
  }