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:
222
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 */
225
203
if (field_arg->comment.length)
227
205
uint32_t tmp_len;
236
214
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
237
215
field_arg->comment.str,"COLUMN COMMENT",
238
216
(uint32_t) COLUMN_COMMENT_MAXLEN);
242
220
if (! use_existing_fields)
258
236
message::Table::Field::FieldOptions *field_options;
259
237
field_options= attribute->mutable_options();
260
field_options->set_default_expression("CURRENT_TIMESTAMP");
238
field_options->set_default_value("NOW()");
263
241
if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
266
244
message::Table::Field::FieldOptions *field_options;
267
245
field_options= attribute->mutable_options();
268
field_options->set_update_expression("CURRENT_TIMESTAMP");
246
field_options->set_update_value("NOW()");
271
if (field_arg->def == NULL && not attribute->constraints().is_notnull())
249
if (field_arg->def == NULL && attribute->constraints().is_nullable())
273
251
message::Table::Field::FieldOptions *field_options;
274
252
field_options= attribute->mutable_options();
297
275
< default_value->length()))
299
277
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
281
if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
339
282
&& field_arg->charset==&my_charset_bin)
340
283
|| (field_arg->sql_type==DRIZZLE_TYPE_BLOB
365
308
if (create_info->table_options & HA_OPTION_PACK_RECORD)
366
309
table_options->set_pack_record(true);
368
if (table_options->has_comment() && table_options->comment().length() == 0)
369
table_options->clear_comment();
371
311
if (table_options->has_comment())
373
313
uint32_t tmp_len;
382
322
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
383
323
table_options->comment().c_str(),"Table COMMENT",
384
324
(uint32_t) TABLE_COMMENT_MAXLEN);
389
329
if (create_info->default_table_charset)
391
table_options->set_collation_id(create_info->default_table_charset->number);
331
table_options->set_collation_id(
332
create_info->default_table_charset->number);
392
333
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
336
if (create_info->auto_increment_value)
401
337
table_options->set_auto_increment_value(create_info->auto_increment_value);
442
378
idx->set_is_unique(false);
444
message::Table::Index::Options *index_options= idx->mutable_options();
380
message::Table::Index::IndexOptions *index_options= idx->mutable_options();
446
382
if (key_info[i].flags & HA_USES_BLOCK_SIZE)
447
383
index_options->set_key_block_size(key_info[i].block_size);
478
414
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
479
415
key_info[i].comment.str,"Index COMMENT",
480
416
(uint32_t) TABLE_COMMENT_MAXLEN);
484
420
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)
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))
495
426
abort(); // Invalid (unknown) index flag.
497
428
for(unsigned int j=0; j< key_info[i].key_parts; j++)
499
430
message::Table::Index::IndexPart *idxpart;
500
const int fieldnr= key_info[i].key_part[j].fieldnr;
503
432
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());
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);
578
465
bool rea_create_table(Session *session,
579
const identifier::Table &identifier,
466
TableIdentifier &identifier,
580
467
message::Table &table_proto,
581
468
HA_CREATE_INFO *create_info,
582
469
List<CreateField> &create_fields,
583
uint32_t keys, KeyInfo *key_info)
470
uint32_t keys, KEY *key_info)
585
assert(table_proto.has_name());
586
if (fill_table_proto(table_proto, create_fields, create_info,
472
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,
476
if (plugin::StorageEngine::createTable(*session,