17 #include <drizzled/error.h>
18 #include <drizzled/session.h>
22 #include <drizzled/plugin/storage_engine.h>
24 #include <drizzled/internal/my_sys.h>
25 #include <drizzled/typelib.h>
26 #include <drizzled/util/test.h>
32 #include <drizzled/message/schema.h>
33 #include <drizzled/message/table.h>
34 #include <google/protobuf/io/zero_copy_stream.h>
35 #include <google/protobuf/io/zero_copy_stream_impl.h>
36 #include <google/protobuf/message.h>
38 #include <drizzled/table_proto.h>
39 #include <drizzled/charset.h>
40 #include <drizzled/create_field.h>
41 #include <drizzled/function/time/typecast.h>
48 bool fill_table_proto(
const identifier::Table& identifier,
49 message::Table &table_proto,
50 List<CreateField> &create_fields,
51 HA_CREATE_INFO *create_info,
55 CreateField *field_arg;
56 List<CreateField>::iterator it(create_fields.begin());
57 message::Table::TableOptions *table_options= table_proto.mutable_options();
59 if (create_fields.size() > MAX_FIELDS)
61 my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
65 assert(strcmp(table_proto.engine().name().c_str(),
66 create_info->db_type->getName().c_str())==0);
68 message::schema::shared_ptr schema_message= plugin::StorageEngine::getSchemaDefinition(identifier);
70 if (schema_message and not message::is_replicated(*schema_message))
72 message::set_is_replicated(table_proto,
false);
76 bool use_existing_fields= table_proto.field_size() > 0;
77 while ((field_arg= it++))
79 message::Table::Field *attribute;
85 if (use_existing_fields)
87 attribute= table_proto.mutable_field(field_number++);
92 attribute= table_proto.add_field();
94 if (field_arg->flags & NOT_NULL_FLAG)
96 attribute->mutable_constraints()->set_is_notnull(
true);
99 if (field_arg->flags & UNSIGNED_FLAG and
100 (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
102 field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
103 attribute->mutable_constraints()->set_is_unsigned(
true);
106 attribute->set_name(field_arg->field_name);
109 assert(((field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_notnull());
110 assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
113 message::Table::Field::FieldType parser_type= attribute->type();
115 if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
117 my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
121 if (field_arg->flags & UNSIGNED_FLAG and
122 (field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
124 message::Table::Field::FieldConstraints *constraints= attribute->mutable_constraints();
126 field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
127 constraints->set_is_unsigned(
true);
130 attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
132 switch (attribute->type()) {
133 case message::Table::Field::BIGINT:
134 case message::Table::Field::INTEGER:
135 case message::Table::Field::DATE:
136 case message::Table::Field::DATETIME:
137 case message::Table::Field::UUID:
138 case message::Table::Field::IPV6:
139 case message::Table::Field::TIME:
140 case message::Table::Field::BOOLEAN:
142 case message::Table::Field::DOUBLE:
148 if (field_arg->decimals != NOT_FIXED_DEC)
150 message::Table::Field::NumericFieldOptions *numeric_field_options;
152 numeric_field_options= attribute->mutable_numeric_options();
154 numeric_field_options->set_precision(field_arg->length);
155 numeric_field_options->set_scale(field_arg->decimals);
159 case message::Table::Field::VARCHAR:
161 message::Table::Field::StringFieldOptions *string_field_options;
163 string_field_options= attribute->mutable_string_options();
165 if (! use_existing_fields || string_field_options->length()==0)
166 string_field_options->set_length(field_arg->length
167 / field_arg->charset->mbmaxlen);
169 assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
171 if (! string_field_options->has_collation())
173 string_field_options->set_collation_id(field_arg->charset->number);
174 string_field_options->set_collation(field_arg->charset->name);
178 case message::Table::Field::DECIMAL:
180 message::Table::Field::NumericFieldOptions *numeric_field_options;
182 numeric_field_options= attribute->mutable_numeric_options();
184 numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
185 numeric_field_options->set_scale(field_arg->decimals);
188 case message::Table::Field::ENUM:
190 message::Table::Field::EnumerationValues *enumeration_options;
192 assert(field_arg->interval);
194 enumeration_options= attribute->mutable_enumeration_values();
196 for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
198 const char *src= field_arg->interval->type_names[pos];
200 enumeration_options->add_field_value(src);
202 enumeration_options->set_collation_id(field_arg->charset->number);
203 enumeration_options->set_collation(field_arg->charset->name);
207 case message::Table::Field::BLOB:
209 message::Table::Field::StringFieldOptions *string_field_options;
211 string_field_options= attribute->mutable_string_options();
212 string_field_options->set_collation_id(field_arg->charset->number);
213 string_field_options->set_collation(field_arg->charset->name);
218 case message::Table::Field::EPOCH:
220 if (field_arg->sql_type == DRIZZLE_TYPE_MICROTIME)
221 attribute->mutable_time_options()->set_microseconds(
true);
227 assert (!use_existing_fields || parser_type == attribute->type());
230 field_constraints= attribute->mutable_constraints();
231 constraints->set_is_nullable(field_arg->def->null_value);
234 if (not field_arg->comment.empty())
236 uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
237 field_arg->comment.begin(),
238 field_arg->comment.end(),
239 COLUMN_COMMENT_MAXLEN);
241 if (tmp_len < field_arg->comment.size())
243 my_error(ER_WRONG_STRING_LENGTH, MYF(0), field_arg->comment.data(),
"COLUMN COMMENT", (uint32_t) COLUMN_COMMENT_MAXLEN);
247 if (not use_existing_fields)
248 attribute->set_comment(field_arg->comment.data());
250 assert(strcmp(attribute->comment().c_str(), field_arg->comment.data())==0);
253 if (field_arg->unireg_check == Field::NEXT_NUMBER)
255 message::Table::Field::NumericFieldOptions *field_options;
256 field_options= attribute->mutable_numeric_options();
257 field_options->set_is_autoincrement(
true);
260 if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
261 || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
263 message::Table::Field::FieldOptions *field_options;
264 field_options= attribute->mutable_options();
265 field_options->set_default_expression(
"CURRENT_TIMESTAMP");
268 if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
269 || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
271 message::Table::Field::FieldOptions *field_options;
272 field_options= attribute->mutable_options();
273 field_options->set_update_expression(
"CURRENT_TIMESTAMP");
276 if (field_arg->def == NULL && not attribute->constraints().is_notnull())
278 message::Table::Field::FieldOptions *field_options;
279 field_options= attribute->mutable_options();
281 field_options->set_default_null(
true);
285 message::Table::Field::FieldOptions *field_options;
286 field_options= attribute->mutable_options();
288 if (field_arg->def->is_null())
290 field_options->set_default_null(
true);
295 String *default_value= field_arg->def->val_str(&d);
297 assert(default_value);
299 if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
300 || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
301 && ((field_arg->length / field_arg->charset->mbmaxlen)
302 < default_value->length()))
304 my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
308 if (field::isDateTime(field_arg->sql_type))
312 if (field_arg->def->get_date(ltime, TIME_FUZZY_DATE))
314 my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
315 default_value->c_str());
329 if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
331 Item *typecast=
new Item_datetime_typecast(field_arg->def);
332 typecast->quick_fix_field();
333 typecast->val_str(default_value);
335 else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
337 Item *typecast=
new Item_date_typecast(field_arg->def);
338 typecast->quick_fix_field();
339 typecast->val_str(default_value);
343 if ((field_arg->sql_type == DRIZZLE_TYPE_VARCHAR && field_arg->charset == &my_charset_bin)
344 || (field_arg->sql_type == DRIZZLE_TYPE_BLOB && field_arg->charset == &my_charset_bin))
346 field_options->set_default_bin_value(
string(default_value->c_ptr(), default_value->length()));
350 field_options->set_default_value(default_value->c_ptr());
355 assert(field_arg->unireg_check == Field::NONE
356 || field_arg->unireg_check == Field::NEXT_NUMBER
357 || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
358 || field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
359 || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD);
363 assert(! use_existing_fields || (field_number == table_proto.field_size()));
365 if (create_info->table_options & HA_OPTION_PACK_RECORD)
366 table_options->set_pack_record(
true);
368 if (table_options->has_comment() && table_options->comment().length() == 0)
369 table_options->clear_comment();
371 if (table_options->has_comment())
374 tmp_len= system_charset_info->cset->charpos(system_charset_info,
375 table_options->comment().c_str(),
376 table_options->comment().c_str() +
377 table_options->comment().length(),
378 TABLE_COMMENT_MAXLEN);
380 if (tmp_len < table_options->comment().length())
382 my_error(ER_WRONG_STRING_LENGTH, MYF(0),
383 table_options->comment().c_str(),
"Table COMMENT",
384 (uint32_t) TABLE_COMMENT_MAXLEN);
389 if (create_info->default_table_charset)
391 table_options->set_collation_id(create_info->default_table_charset->number);
392 table_options->set_collation(create_info->default_table_charset->name);
395 if (create_info->used_fields & HA_CREATE_USED_AUTO)
396 table_options->set_has_user_set_auto_increment_value(
true);
398 table_options->set_has_user_set_auto_increment_value(
false);
400 if (create_info->auto_increment_value)
401 table_options->set_auto_increment_value(create_info->auto_increment_value);
403 for (uint32_t i= 0; i < keys; i++)
405 message::Table::Index *idx= table_proto.add_indexes();
407 assert(test(key_info[i].flags & HA_USES_COMMENT) == (key_info[i].comment.size() > 0));
409 idx->set_name(key_info[i].name);
410 idx->set_key_length(key_info[i].key_length);
411 idx->set_is_primary(is_primary_key(key_info[i].name));
413 switch(key_info[i].algorithm)
415 case HA_KEY_ALG_HASH:
416 idx->set_type(message::Table::Index::HASH);
419 case HA_KEY_ALG_BTREE:
420 idx->set_type(message::Table::Index::BTREE);
423 case HA_KEY_ALG_UNDEF:
425 idx->set_type(create_info->db_type->default_index_type());
430 if (key_info[i].flags & HA_NOSAME)
431 idx->set_is_unique(
true);
433 idx->set_is_unique(
false);
435 message::Table::Index::Options *index_options= idx->mutable_options();
437 if (key_info[i].flags & HA_USES_BLOCK_SIZE)
438 index_options->set_key_block_size(key_info[i].block_size);
440 if (key_info[i].flags & HA_PACK_KEY)
441 index_options->set_pack_key(
true);
443 if (key_info[i].flags & HA_BINARY_PACK_KEY)
444 index_options->set_binary_pack_key(
true);
446 if (key_info[i].flags & HA_VAR_LENGTH_PART)
447 index_options->set_var_length_key(
true);
449 if (key_info[i].flags & HA_NULL_PART_KEY)
450 index_options->set_null_part_key(
true);
452 if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
453 index_options->set_has_partial_segments(
true);
455 if (key_info[i].flags & HA_GENERATED_KEY)
456 index_options->set_auto_generated_key(
true);
458 if (key_info[i].flags & HA_USES_COMMENT)
461 tmp_len= system_charset_info->cset->charpos(system_charset_info,
462 key_info[i].comment.begin(),
463 key_info[i].comment.end(),
464 TABLE_COMMENT_MAXLEN);
466 if (tmp_len < key_info[i].comment.size())
468 my_error(ER_WRONG_STRING_LENGTH, MYF(0),
469 key_info[i].comment.data(),
"Index COMMENT",
470 (uint32_t) TABLE_COMMENT_MAXLEN);
474 idx->set_comment(key_info[i].comment.data());
476 static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
481 HA_KEY_HAS_PART_KEY_SEG |
484 if (key_info[i].flags & ~unknown_index_flag)
487 for(
unsigned int j=0; j< key_info[i].key_parts; j++)
489 message::Table::Index::IndexPart *idxpart;
490 const int fieldnr= key_info[i].key_part[j].fieldnr;
493 idxpart= idx->add_index_part();
495 idxpart->set_fieldnr(fieldnr);
497 if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
498 || table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
500 uint32_t collation_id;
502 if (table_proto.field(fieldnr).string_options().has_collation_id())
503 collation_id= table_proto.field(fieldnr).string_options().collation_id();
505 collation_id= table_proto.options().collation_id();
507 const charset_info_st *cs= get_charset(collation_id);
509 mbmaxlen= cs->mbmaxlen;
512 idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
516 if (not table_proto.IsInitialized())
518 my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
519 table_proto.name().c_str(),
520 table_proto.InitializationErrorString().c_str());
533 table_proto.SerializeToString(&tmp_string);
538 my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
539 table_proto.name().c_str(),
540 table_proto.InitializationErrorString().c_str());
568 bool rea_create_table(Session *session,
569 const identifier::Table &identifier,
570 message::Table &table_proto,
571 HA_CREATE_INFO *create_info,
572 List<CreateField> &create_fields,
573 uint32_t keys, KeyInfo *key_info)
575 assert(table_proto.has_name());
577 if (fill_table_proto(identifier,
578 table_proto, create_fields, create_info,
584 assert(table_proto.name() == identifier.getTableName());
586 if (not plugin::StorageEngine::createTable(*session,
TODO: Rename this file - func.h is stupid.