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 */
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>
37
36
#include <drizzled/table_proto.h>
38
#include <drizzled/charset.h>
40
#include "drizzled/function/time/typecast.h"
42
38
using namespace std;
44
40
namespace drizzled {
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,
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);
62
assert(table_proto.name() == table_name);
65
64
int field_number= 0;
66
65
bool use_existing_fields= table_proto.field_size() > 0;
67
66
while ((field_arg= it++))
97
96
message::Table::Field::FieldType parser_type= attribute->type();
99
if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
101
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
105
98
attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
107
100
switch (attribute->type()) {
190
183
constraints->set_is_nullable(field_arg->def->null_value);
186
switch(field_arg->column_format())
188
case COLUMN_FORMAT_TYPE_NOT_USED:
190
case COLUMN_FORMAT_TYPE_DEFAULT:
191
attribute->set_format(message::Table::Field::DefaultFormat);
193
case COLUMN_FORMAT_TYPE_FIXED:
194
attribute->set_format(message::Table::Field::FixedFormat);
196
case COLUMN_FORMAT_TYPE_DYNAMIC:
197
attribute->set_format(message::Table::Field::DynamicFormat);
200
assert(0); /* Tell us, since this shouldn't happend */
193
203
if (field_arg->comment.length)
195
205
uint32_t tmp_len;
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()");
231
241
if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
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()");
239
249
if (field_arg->def == NULL && attribute->constraints().is_nullable())
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)
277
if (field_arg->def->get_date(<ime, TIME_FUZZY_DATE))
279
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
280
default_value->c_str());
284
/* We now do the casting down to the appropriate type.
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.
291
the timestamp errors are taken care of elsewhere.
294
if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
296
Item *typecast= new Item_datetime_typecast(field_arg->def);
297
typecast->quick_fix_field();
298
typecast->val_str(default_value);
300
else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
302
Item *typecast= new Item_date_typecast(field_arg->def);
303
typecast->quick_fix_field();
304
typecast->val_str(default_value);
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);
338
if (table_options->has_comment() && table_options->comment().length() == 0)
339
table_options->clear_comment();
341
311
if (table_options->has_comment())
343
313
uint32_t tmp_len;
363
333
table_options->set_collation(create_info->default_table_charset->name);
366
if (create_info->used_fields & HA_CREATE_USED_AUTO)
367
table_options->set_has_user_set_auto_increment_value(true);
369
table_options->set_has_user_set_auto_increment_value(false);
371
336
if (create_info->auto_increment_value)
372
337
table_options->set_auto_increment_value(create_info->auto_increment_value);
413
378
idx->set_is_unique(false);
415
message::Table::Index::Options *index_options= idx->mutable_options();
380
message::Table::Index::IndexOptions *index_options= idx->mutable_options();
417
382
if (key_info[i].flags & HA_USES_BLOCK_SIZE)
418
383
index_options->set_key_block_size(key_info[i].block_size);
455
420
idx->set_comment(key_info[i].comment.str);
457
static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
462
HA_KEY_HAS_PART_KEY_SEG |
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.
468
428
for(unsigned int j=0; j< key_info[i].key_parts; j++)
470
430
message::Table::Index::IndexPart *idxpart;
471
const int fieldnr= key_info[i].key_part[j].fieldnr;
474
432
idxpart= idx->add_index_part();
476
idxpart->set_fieldnr(fieldnr);
478
if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
479
|| table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
481
uint32_t collation_id;
483
if (table_proto.field(fieldnr).string_options().has_collation_id())
484
collation_id= table_proto.field(fieldnr).string_options().collation_id();
486
collation_id= table_proto.options().collation_id();
488
const CHARSET_INFO *cs= get_charset(collation_id);
490
mbmaxlen= cs->mbmaxlen;
493
idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
497
if (not table_proto.IsInitialized())
499
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
504
Here we test to see if we can validate the Table Message before we continue.
505
We do this by serializing the protobuffer.
511
table_proto.SerializeToString(&tmp_string);
516
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
517
table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
434
idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
436
idxpart->set_compare_length(key_info[i].key_part[j].length);
438
idxpart->set_key_type(key_info[i].key_part[j].key_type);
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)
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,
557
assert(table_proto.name() == identifier.getTableName());
559
476
if (plugin::StorageEngine::createTable(*session,