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 */
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>
24
#include <drizzled/plugin/storage_engine.h>
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"
24
#include "drizzled/internal/my_sys.h"
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>
39
36
#include <drizzled/table_proto.h>
40
#include <drizzled/charset.h>
42
#include <drizzled/function/time/typecast.h>
44
38
using namespace std;
46
40
namespace drizzled {
48
bool fill_table_proto(message::Table &table_proto,
49
List<CreateField> &create_fields,
50
HA_CREATE_INFO *create_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,
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();
58
53
if (create_fields.elements > MAX_FIELDS)
60
55
my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
64
59
assert(strcmp(table_proto.engine().name().c_str(),
65
60
create_info->db_type->getName().c_str())==0);
62
assert(table_proto.name() == table_name);
67
64
int field_number= 0;
68
65
bool use_existing_fields= table_proto.field_size() > 0;
69
66
while ((field_arg= it++))
86
81
if (field_arg->flags & NOT_NULL_FLAG)
88
attribute->mutable_constraints()->set_is_notnull(true);
83
message::Table::Field::FieldConstraints *constraints;
91
if (field_arg->flags & UNSIGNED_FLAG and
92
(field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
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);
98
89
attribute->set_name(field_arg->field_name);
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);
105
96
message::Table::Field::FieldType parser_type= attribute->type();
107
if (field_arg->sql_type == DRIZZLE_TYPE_NULL)
109
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), table_proto.name().c_str(), -1);
113
if (field_arg->flags & UNSIGNED_FLAG and
114
(field_arg->sql_type == DRIZZLE_TYPE_LONGLONG or field_arg->sql_type == DRIZZLE_TYPE_LONG))
116
message::Table::Field::FieldConstraints *constraints= attribute->mutable_constraints();
118
field_arg->sql_type= DRIZZLE_TYPE_LONGLONG;
119
constraints->set_is_unsigned(true);
122
98
attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
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 */
133
103
case message::Table::Field::DOUBLE:
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);
242
203
if (! use_existing_fields)
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()");
263
224
if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
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()");
271
if (field_arg->def == NULL && not attribute->constraints().is_notnull())
232
if (field_arg->def == NULL && attribute->constraints().is_nullable())
273
234
message::Table::Field::FieldOptions *field_options;
274
235
field_options= attribute->mutable_options();
297
258
< default_value->length()))
299
260
my_error(ER_INVALID_DEFAULT, MYF(0), field_arg->field_name);
303
if (field::isDateTime(field_arg->sql_type))
307
if (field_arg->def->get_date(ltime, TIME_FUZZY_DATE))
309
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR),
310
default_value->c_str());
314
/* We now do the casting down to the appropriate type.
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.
321
the timestamp errors are taken care of elsewhere.
324
if (field_arg->sql_type == DRIZZLE_TYPE_DATETIME)
326
Item *typecast= new Item_datetime_typecast(field_arg->def);
327
typecast->quick_fix_field();
328
typecast->val_str(default_value);
330
else if (field_arg->sql_type == DRIZZLE_TYPE_DATE)
332
Item *typecast= new Item_date_typecast(field_arg->def);
333
typecast->quick_fix_field();
334
typecast->val_str(default_value);
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);
368
if (table_options->has_comment() && table_options->comment().length() == 0)
369
table_options->clear_comment();
371
294
if (table_options->has_comment())
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);
389
312
if (create_info->default_table_charset)
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);
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
319
if (create_info->auto_increment_value)
401
320
table_options->set_auto_increment_value(create_info->auto_increment_value);
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);
484
403
idx->set_comment(key_info[i].comment.str);
486
static const uint64_t unknown_index_flag= (HA_NOSAME | HA_PACK_KEY |
491
HA_KEY_HAS_PART_KEY_SEG |
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.
497
411
for(unsigned int j=0; j< key_info[i].key_parts; j++)
499
413
message::Table::Index::IndexPart *idxpart;
500
const int fieldnr= key_info[i].key_part[j].fieldnr;
503
415
idxpart= idx->add_index_part();
505
idxpart->set_fieldnr(fieldnr);
507
if (table_proto.field(fieldnr).type() == message::Table::Field::VARCHAR
508
|| table_proto.field(fieldnr).type() == message::Table::Field::BLOB)
510
uint32_t collation_id;
512
if (table_proto.field(fieldnr).string_options().has_collation_id())
513
collation_id= table_proto.field(fieldnr).string_options().collation_id();
515
collation_id= table_proto.options().collation_id();
517
const CHARSET_INFO *cs= get_charset(collation_id);
519
mbmaxlen= cs->mbmaxlen;
522
idxpart->set_compare_length(key_info[i].key_part[j].length / mbmaxlen);
526
if (not table_proto.IsInitialized())
528
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
529
table_proto.name().c_str(),
530
table_proto.InitializationErrorString().c_str());
536
Here we test to see if we can validate the Table Message before we continue.
537
We do this by serializing the protobuffer.
543
table_proto.SerializeToString(&tmp_string);
548
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
549
table_proto.name().c_str(),
550
table_proto.InitializationErrorString().c_str());
417
idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
419
idxpart->set_compare_length(key_info[i].key_part[j].length);
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)
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,
592
assert(table_proto.name() == identifier.getTableName());
594
if (not plugin::StorageEngine::createTable(*session,
456
if (plugin::StorageEngine::createTable(*session,