~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_proto_write.cc

  • Committer: Jay Pipes
  • Date: 2009-09-15 21:01:42 UTC
  • mto: (1126.2.5 merge)
  • mto: This revision was merged to the branch mainline in revision 1128.
  • Revision ID: jpipes@serialcoder-20090915210142-x8mwiqn1q0vzjspp
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.

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 <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/plugin/storage_engine.h>
25
 
 
26
 
#include "drizzled/internal/my_sys.h"
27
 
 
28
20
 
29
21
/* For proto */
30
22
#include <string>
31
23
#include <fstream>
32
 
#include <fcntl.h>
33
24
#include <drizzled/message/schema.pb.h>
34
25
#include <drizzled/message/table.pb.h>
35
26
#include <google/protobuf/io/zero_copy_stream.h>
36
27
#include <google/protobuf/io/zero_copy_stream_impl.h>
37
 
#include <google/protobuf/message.h>
38
28
 
39
29
#include <drizzled/table_proto.h>
40
 
#include <drizzled/charset.h>
41
 
 
42
 
#include "drizzled/function/time/typecast.h"
43
 
 
44
30
using namespace std;
45
 
 
46
 
namespace drizzled {
47
 
 
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)
 
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)
53
39
{
54
40
  CreateField *field_arg;
55
41
  List_iterator<CreateField> it(create_fields);
56
 
  message::Table::TableOptions *table_options= table_proto.mutable_options();
 
42
  message::Table::TableOptions *table_options= table_proto->mutable_options();
57
43
 
58
44
  if (create_fields.elements > MAX_FIELDS)
59
45
  {
60
46
    my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
61
 
    return true;
 
47
    return(1);
62
48
  }
63
49
 
64
 
  assert(strcmp(table_proto.engine().name().c_str(),
 
50
  assert(strcmp(table_proto->engine().name().c_str(),
65
51
                create_info->db_type->getName().c_str())==0);
66
52
 
67
 
  int field_number= 0;
68
 
  bool use_existing_fields= table_proto.field_size() > 0;
 
53
  assert(strcmp(table_proto->name().c_str(),table_name)==0);
 
54
 
69
55
  while ((field_arg= it++))
70
56
  {
71
57
    message::Table::Field *attribute;
72
58
 
73
 
    /* some (one) code path for CREATE TABLE fills the proto
74
 
       out more than the others, so we already have partially
75
 
       filled out Field messages */
76
 
 
77
 
    if (use_existing_fields)
78
 
    {
79
 
      attribute= table_proto.mutable_field(field_number++);
80
 
    }
81
 
    else
82
 
    {
83
 
      /* Other code paths still have to fill out the proto */
84
 
      attribute= table_proto.add_field();
85
 
 
86
 
      if (field_arg->flags & NOT_NULL_FLAG)
87
 
      {
88
 
        attribute->mutable_constraints()->set_is_notnull(true);
89
 
      }
90
 
 
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);
96
 
      }
97
 
 
98
 
      attribute->set_name(field_arg->field_name);
99
 
    }
100
 
 
101
 
    assert(((field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_notnull());
102
 
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
103
 
 
104
 
 
105
 
    message::Table::Field::FieldType parser_type= attribute->type();
106
 
 
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
 
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
123
 
 
124
 
    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:
132
 
      break;
133
 
    case message::Table::Field::DOUBLE:
134
 
      {
135
 
        /*
136
 
         * For DOUBLE, we only add a specific scale and precision iff
137
 
         * the fixed decimal point has been specified...
138
 
         */
139
 
        if (field_arg->decimals != NOT_FIXED_DEC)
140
 
        {
141
 
          message::Table::Field::NumericFieldOptions *numeric_field_options;
142
 
 
143
 
          numeric_field_options= attribute->mutable_numeric_options();
144
 
 
145
 
          numeric_field_options->set_precision(field_arg->length);
146
 
          numeric_field_options->set_scale(field_arg->decimals);
147
 
        }
148
 
      }
149
 
      break;
150
 
    case message::Table::Field::VARCHAR:
 
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))
 
65
    {
 
66
      message::Table::Field::FieldConstraints *constraints;
 
67
 
 
68
      constraints= attribute->mutable_constraints();
 
69
      constraints->set_is_nullable(true);
 
70
    }
 
71
 
 
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:
151
97
      {
152
98
        message::Table::Field::StringFieldOptions *string_field_options;
153
99
 
154
100
        string_field_options= attribute->mutable_string_options();
155
 
 
156
 
        if (! use_existing_fields || string_field_options->length()==0)
157
 
          string_field_options->set_length(field_arg->length
158
 
                                           / field_arg->charset->mbmaxlen);
159
 
        else
160
 
          assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
161
 
 
162
 
        if (! string_field_options->has_collation())
163
 
        {
164
 
          string_field_options->set_collation_id(field_arg->charset->number);
165
 
          string_field_options->set_collation(field_arg->charset->name);
166
 
        }
 
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
 
167
107
        break;
168
108
      }
169
 
    case message::Table::Field::DECIMAL:
 
109
    case DRIZZLE_TYPE_NEWDECIMAL:
170
110
      {
171
111
        message::Table::Field::NumericFieldOptions *numeric_field_options;
172
112
 
 
113
        attribute->set_type(message::Table::Field::DECIMAL);
173
114
        numeric_field_options= attribute->mutable_numeric_options();
174
115
        /* This is magic, I hate magic numbers -Brian */
175
116
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
176
117
        numeric_field_options->set_scale(field_arg->decimals);
177
118
        break;
178
119
      }
179
 
    case message::Table::Field::ENUM:
 
120
    case DRIZZLE_TYPE_ENUM:
180
121
      {
181
 
        message::Table::Field::EnumerationValues *enumeration_options;
 
122
        message::Table::Field::SetFieldOptions *set_field_options;
182
123
 
183
124
        assert(field_arg->interval);
184
125
 
185
 
        enumeration_options= attribute->mutable_enumeration_values();
 
126
        attribute->set_type(message::Table::Field::ENUM);
 
127
        set_field_options= attribute->mutable_set_options();
186
128
 
187
129
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
188
130
        {
189
131
          const char *src= field_arg->interval->type_names[pos];
190
132
 
191
 
          enumeration_options->add_field_value(src);
 
133
          set_field_options->add_field_value(src);
192
134
        }
193
 
        enumeration_options->set_collation_id(field_arg->charset->number);
194
 
        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);
195
138
        break;
196
139
      }
 
140
    case DRIZZLE_TYPE_BLOB:
 
141
      {
 
142
        attribute->set_type(message::Table::Field::BLOB);
197
143
 
198
 
    case message::Table::Field::BLOB:
199
 
      {
200
144
        message::Table::Field::StringFieldOptions *string_field_options;
201
145
 
202
146
        string_field_options= attribute->mutable_string_options();
205
149
      }
206
150
 
207
151
      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;
 
152
    default:
 
153
      assert(0); /* Tell us, since this shouldn't happend */
216
154
    }
217
155
 
218
 
    assert (!use_existing_fields || parser_type == attribute->type());
219
 
 
220
156
#ifdef NOTDONE
221
157
    field_constraints= attribute->mutable_constraints();
222
158
    constraints->set_is_nullable(field_arg->def->null_value);
223
159
#endif
224
160
 
 
161
    switch(field_arg->column_format())
 
162
    {
 
163
    case COLUMN_FORMAT_TYPE_NOT_USED:
 
164
      break;
 
165
    case COLUMN_FORMAT_TYPE_DEFAULT:
 
166
      attribute->set_format(message::Table::Field::DefaultFormat);
 
167
      break;
 
168
    case COLUMN_FORMAT_TYPE_FIXED:
 
169
      attribute->set_format(message::Table::Field::FixedFormat);
 
170
      break;
 
171
    case COLUMN_FORMAT_TYPE_DYNAMIC:
 
172
      attribute->set_format(message::Table::Field::DynamicFormat);
 
173
      break;
 
174
    default:
 
175
      assert(0); /* Tell us, since this shouldn't happend */
 
176
    }
 
177
 
225
178
    if (field_arg->comment.length)
226
179
    {
227
180
      uint32_t tmp_len;
236
189
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
237
190
                 field_arg->comment.str,"COLUMN COMMENT",
238
191
                 (uint32_t) COLUMN_COMMENT_MAXLEN);
239
 
        return true;
 
192
        return(1);
240
193
      }
241
194
 
242
 
      if (! use_existing_fields)
243
 
        attribute->set_comment(field_arg->comment.str);
244
 
 
245
 
      assert(strcmp(attribute->comment().c_str(), field_arg->comment.str)==0);
 
195
      attribute->set_comment(field_arg->comment.str);
246
196
    }
247
197
 
248
 
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
 
198
    if(field_arg->unireg_check == Field::NEXT_NUMBER)
249
199
    {
250
200
      message::Table::Field::NumericFieldOptions *field_options;
251
201
      field_options= attribute->mutable_numeric_options();
252
202
      field_options->set_is_autoincrement(true);
253
203
    }
254
204
 
255
 
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
256
 
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
257
 
    {
258
 
      message::Table::Field::FieldOptions *field_options;
259
 
      field_options= attribute->mutable_options();
260
 
      field_options->set_default_expression("CURRENT_TIMESTAMP");
261
 
    }
262
 
 
263
 
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
264
 
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
265
 
    {
266
 
      message::Table::Field::FieldOptions *field_options;
267
 
      field_options= attribute->mutable_options();
268
 
      field_options->set_update_expression("CURRENT_TIMESTAMP");
269
 
    }
270
 
 
271
 
    if (field_arg->def == NULL  && not attribute->constraints().is_notnull())
272
 
    {
273
 
      message::Table::Field::FieldOptions *field_options;
274
 
      field_options= attribute->mutable_options();
275
 
 
276
 
      field_options->set_default_null(true);
277
 
    }
278
 
    if (field_arg->def)
279
 
    {
280
 
      message::Table::Field::FieldOptions *field_options;
281
 
      field_options= attribute->mutable_options();
282
 
 
283
 
      if (field_arg->def->is_null())
 
205
    if(field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
 
206
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
 
207
    {
 
208
      message::Table::Field::FieldOptions *field_options;
 
209
      field_options= attribute->mutable_options();
 
210
      field_options->set_default_value("NOW()");
 
211
    }
 
212
 
 
213
    if(field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
 
214
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
 
215
    {
 
216
      message::Table::Field::FieldOptions *field_options;
 
217
      field_options= attribute->mutable_options();
 
218
      field_options->set_update_value("NOW()");
 
219
    }
 
220
 
 
221
    if(field_arg->def)
 
222
    {
 
223
      message::Table::Field::FieldOptions *field_options;
 
224
      field_options= attribute->mutable_options();
 
225
 
 
226
      if(field_arg->def->is_null())
284
227
      {
285
228
        field_options->set_default_null(true);
286
229
      }
291
234
 
292
235
        assert(default_value);
293
236
 
294
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
 
237
        if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
295
238
           || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
296
239
           && ((field_arg->length / field_arg->charset->mbmaxlen)
297
240
           < default_value->length()))
298
241
        {
299
242
          my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
300
 
          return true;
 
243
          return 1;
301
244
        }
302
245
 
303
 
        if (field_arg->sql_type == DRIZZLE_TYPE_DATE
304
 
            || field_arg->sql_type == DRIZZLE_TYPE_TIME
305
 
            || field_arg->sql_type == DRIZZLE_TYPE_DATETIME
306
 
            || field_arg->sql_type == DRIZZLE_TYPE_MICROTIME
307
 
            || field_arg->sql_type == DRIZZLE_TYPE_TIMESTAMP)
308
 
        {
309
 
          type::Time ltime;
310
 
 
311
 
          if (field_arg->def->get_date(ltime, TIME_FUZZY_DATE))
312
 
          {
313
 
            my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
314
 
                     default_value->c_str());
315
 
            return true;
316
 
          }
317
 
 
318
 
          /* We now do the casting down to the appropriate type.
319
 
 
320
 
             Yes, this implicit casting is balls.
321
 
             It was previously done on reading the proto back in,
322
 
             but we really shouldn't store the bogus things in the proto,
323
 
             and instead do the casting behaviour here.
324
 
 
325
 
             the timestamp errors are taken care of elsewhere.
326
 
          */
327
 
 
328
 
          if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
329
 
          {
330
 
            Item *typecast= new Item_datetime_typecast(field_arg->def);
331
 
            typecast->quick_fix_field();
332
 
            typecast->val_str(default_value);
333
 
          }
334
 
          else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
335
 
          {
336
 
            Item *typecast= new Item_date_typecast(field_arg->def);
337
 
            typecast->quick_fix_field();
338
 
            typecast->val_str(default_value);
339
 
          }
340
 
        }
341
 
 
342
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
 
246
        if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
343
247
            && field_arg->charset==&my_charset_bin)
344
248
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
345
249
            && field_arg->charset==&my_charset_bin))
356
260
      }
357
261
    }
358
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
 
359
270
    assert(field_arg->unireg_check == Field::NONE
360
271
           || field_arg->unireg_check == Field::NEXT_NUMBER
361
272
           || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
364
275
 
365
276
  }
366
277
 
367
 
  assert(! use_existing_fields || (field_number == table_proto.field_size()));
368
 
 
369
 
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
370
 
    table_options->set_pack_record(true);
371
 
 
372
 
  if (table_options->has_comment() && table_options->comment().length() == 0)
373
 
    table_options->clear_comment();
 
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
  }
 
304
 
 
305
  table_options->set_pack_record(create_info->table_options
 
306
                                 & HA_OPTION_PACK_RECORD);
374
307
 
375
308
  if (table_options->has_comment())
376
309
  {
386
319
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
387
320
               table_options->comment().c_str(),"Table COMMENT",
388
321
               (uint32_t) TABLE_COMMENT_MAXLEN);
389
 
      return true;
 
322
      return(1);
390
323
    }
391
324
  }
392
325
 
393
326
  if (create_info->default_table_charset)
394
327
  {
395
 
    table_options->set_collation_id(create_info->default_table_charset->number);
 
328
    table_options->set_collation_id(
 
329
                               create_info->default_table_charset->number);
396
330
    table_options->set_collation(create_info->default_table_charset->name);
397
331
  }
398
332
 
399
 
  if (create_info->used_fields & HA_CREATE_USED_AUTO)
400
 
    table_options->set_has_user_set_auto_increment_value(true);
401
 
  else
402
 
    table_options->set_has_user_set_auto_increment_value(false);
403
 
 
404
333
  if (create_info->auto_increment_value)
405
334
    table_options->set_auto_increment_value(create_info->auto_increment_value);
406
335
 
407
 
  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++)
408
343
  {
409
344
    message::Table::Index *idx;
410
345
 
411
 
    idx= table_proto.add_indexes();
 
346
    idx= table_proto->add_indexes();
412
347
 
413
348
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
414
349
           (key_info[i].comment.length > 0));
417
352
 
418
353
    idx->set_key_length(key_info[i].key_length);
419
354
 
420
 
    if (is_primary_key_name(key_info[i].name))
 
355
    if(is_primary_key_name(key_info[i].name))
421
356
      idx->set_is_primary(true);
422
357
    else
423
358
      idx->set_is_primary(false);
432
367
      idx->set_type(message::Table::Index::BTREE);
433
368
      break;
434
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);
435
374
    case HA_KEY_ALG_UNDEF:
436
375
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
437
376
      break;
445
384
    else
446
385
      idx->set_is_unique(false);
447
386
 
448
 
    message::Table::Index::Options *index_options= idx->mutable_options();
 
387
    message::Table::Index::IndexOptions *index_options= idx->mutable_options();
449
388
 
450
 
    if (key_info[i].flags & HA_USES_BLOCK_SIZE)
 
389
    if(key_info[i].flags & HA_USES_BLOCK_SIZE)
451
390
      index_options->set_key_block_size(key_info[i].block_size);
452
391
 
453
 
    if (key_info[i].flags & HA_PACK_KEY)
 
392
    if(key_info[i].flags & HA_PACK_KEY)
454
393
      index_options->set_pack_key(true);
455
394
 
456
 
    if (key_info[i].flags & HA_BINARY_PACK_KEY)
 
395
    if(key_info[i].flags & HA_BINARY_PACK_KEY)
457
396
      index_options->set_binary_pack_key(true);
458
397
 
459
 
    if (key_info[i].flags & HA_VAR_LENGTH_PART)
 
398
    if(key_info[i].flags & HA_VAR_LENGTH_PART)
460
399
      index_options->set_var_length_key(true);
461
400
 
462
 
    if (key_info[i].flags & HA_NULL_PART_KEY)
 
401
    if(key_info[i].flags & HA_NULL_PART_KEY)
463
402
      index_options->set_null_part_key(true);
464
403
 
465
 
    if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
 
404
    if(key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
466
405
      index_options->set_has_partial_segments(true);
467
406
 
468
 
    if (key_info[i].flags & HA_GENERATED_KEY)
 
407
    if(key_info[i].flags & HA_GENERATED_KEY)
469
408
      index_options->set_auto_generated_key(true);
470
409
 
471
410
    if (key_info[i].flags & HA_USES_COMMENT)
482
421
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
483
422
                 key_info[i].comment.str,"Index COMMENT",
484
423
                 (uint32_t) TABLE_COMMENT_MAXLEN);
485
 
        return true;
 
424
        return(1);
486
425
      }
487
426
 
488
427
      idx->set_comment(key_info[i].comment.str);
489
428
    }
490
 
    static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
491
 
                                               HA_USES_BLOCK_SIZE | 
492
 
                                               HA_BINARY_PACK_KEY |
493
 
                                               HA_VAR_LENGTH_PART |
494
 
                                               HA_NULL_PART_KEY | 
495
 
                                               HA_KEY_HAS_PART_KEY_SEG |
496
 
                                               HA_GENERATED_KEY |
497
 
                                               HA_USES_COMMENT);
498
 
    if (key_info[i].flags & ~unknown_index_flag)
 
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))
499
430
      abort(); // Invalid (unknown) index flag.
500
431
 
501
432
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
502
433
    {
503
434
      message::Table::Index::IndexPart *idxpart;
504
 
      const int fieldnr= key_info[i].key_part[j].fieldnr;
505
 
      int mbmaxlen= 1;
506
435
 
507
436
      idxpart= idx->add_index_part();
508
437
 
509
 
      idxpart->set_fieldnr(fieldnr);
510
 
 
511
 
      if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
512
 
          || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
513
 
      {
514
 
        uint32_t collation_id;
515
 
 
516
 
        if (table_proto.field(fieldnr).string_options().has_collation_id())
517
 
          collation_id= table_proto.field(fieldnr).string_options().collation_id();
518
 
        else
519
 
          collation_id= table_proto.options().collation_id();
520
 
 
521
 
        const CHARSET_INFO *cs= get_charset(collation_id);
522
 
 
523
 
        mbmaxlen= cs->mbmaxlen;
524
 
      }
525
 
 
526
 
      idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
527
 
    }
528
 
  }
529
 
 
530
 
  if (not table_proto.IsInitialized())
531
 
  {
532
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
533
 
             table_proto.name().c_str(),
534
 
             table_proto.InitializationErrorString().c_str());
535
 
 
536
 
    return true;
537
 
  }
538
 
 
539
 
  /*
540
 
    Here we test to see if we can validate the Table Message before we continue. 
541
 
    We do this by serializing the protobuffer.
542
 
  */
543
 
  {
544
 
    string tmp_string;
545
 
 
546
 
    try {
547
 
      table_proto.SerializeToString(&tmp_string);
548
 
    }
549
 
 
550
 
    catch (...)
551
 
    {
552
 
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
553
 
               table_proto.name().c_str(),
554
 
               table_proto.InitializationErrorString().c_str());
555
 
 
556
 
      return true;
557
 
    }
558
 
  }
559
 
 
560
 
  return false;
 
438
      idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
 
439
 
 
440
      idxpart->set_compare_length(key_info[i].key_part[j].length);
 
441
 
 
442
      idxpart->set_key_type(key_info[i].key_part[j].key_type);
 
443
 
 
444
    }
 
445
  }
 
446
 
 
447
  return 0;
 
448
}
 
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;
561
492
}
562
493
 
563
494
/*
573
504
    create_fields       Fields to create
574
505
    keys                number of keys to create
575
506
    key_info            Keys to create
 
507
    file                Handler to use
 
508
    is_like             is true for mysql_create_like_schema_frm
576
509
 
577
510
  RETURN
578
511
    0  ok
579
512
    1  error
580
513
*/
581
514
 
582
 
bool rea_create_table(Session *session,
583
 
                      const identifier::Table &identifier,
584
 
                      message::Table &table_proto,
585
 
                      HA_CREATE_INFO *create_info,
586
 
                      List<CreateField> &create_fields,
587
 
                      uint32_t keys, KeyInfo *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)
588
521
{
589
 
  assert(table_proto.has_name());
590
 
  if (fill_table_proto(table_proto, create_fields, create_info,
591
 
                       keys, key_info))
592
 
  {
593
 
    return false;
594
 
  }
595
 
 
596
 
  assert(table_proto.name() == identifier.getTableName());
597
 
 
598
 
  if (not plugin::StorageEngine::createTable(*session,
599
 
                                             identifier,
600
 
                                             table_proto))
601
 
  {
602
 
    return false;
603
 
  }
604
 
 
605
 
  return true;
606
 
 
 
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)
 
542
  {
 
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;
 
549
  }
 
550
 
 
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;
607
561
} /* rea_create_table */
608
 
 
609
 
} /* namespace drizzled */
610