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"
37
35
#include <google/protobuf/message.h>
39
37
#include <drizzled/table_proto.h>
40
#include <drizzled/charset.h>
42
#include <drizzled/function/time/typecast.h>
44
39
using namespace std;
46
41
namespace drizzled {
48
bool fill_table_proto(message::Table &table_proto,
49
List<CreateField> &create_fields,
50
HA_CREATE_INFO *create_info,
43
static int fill_table_proto(message::Table &table_proto,
44
const std::string &table_name,
45
List<CreateField> &create_fields,
46
HA_CREATE_INFO *create_info,
54
50
CreateField *field_arg;
55
List<CreateField>::iterator it(create_fields.begin());
51
List_iterator<CreateField> it(create_fields);
56
52
message::Table::TableOptions *table_options= table_proto.mutable_options();
58
54
if (create_fields.elements > MAX_FIELDS)
60
56
my_error(ER_TOO_MANY_FIELDS, MYF(0), ER(ER_TOO_MANY_FIELDS));
64
60
assert(strcmp(table_proto.engine().name().c_str(),
65
61
create_info->db_type->getName().c_str())==0);
63
assert(table_proto.name() == table_name);
67
65
int field_number= 0;
68
66
bool use_existing_fields= table_proto.field_size() > 0;
69
67
while ((field_arg= it++))
86
82
if (field_arg->flags & NOT_NULL_FLAG)
88
attribute->mutable_constraints()->set_is_notnull(true);
84
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);
86
constraints= attribute->mutable_constraints();
87
constraints->set_is_nullable(false);
98
90
attribute->set_name(field_arg->field_name);
101
assert(((field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_notnull());
93
assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
102
94
assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
105
97
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
99
attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
124
101
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:
102
default: /* Only deal with types that need extra information */
133
104
case message::Table::Field::DOUBLE:
209
case message::Table::Field::EPOCH:
211
if (field_arg->sql_type == DRIZZLE_TYPE_MICROTIME)
212
attribute->mutable_time_options()->set_microseconds(true);
218
180
assert (!use_existing_fields || parser_type == attribute->type());
236
198
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
237
199
field_arg->comment.str,"COLUMN COMMENT",
238
200
(uint32_t) COLUMN_COMMENT_MAXLEN);
242
204
if (! use_existing_fields)
258
220
message::Table::Field::FieldOptions *field_options;
259
221
field_options= attribute->mutable_options();
260
field_options->set_default_expression("CURRENT_TIMESTAMP");
222
field_options->set_default_value("NOW()");
263
225
if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
266
228
message::Table::Field::FieldOptions *field_options;
267
229
field_options= attribute->mutable_options();
268
field_options->set_update_expression("CURRENT_TIMESTAMP");
230
field_options->set_update_value("NOW()");
271
if (field_arg->def == NULL && not attribute->constraints().is_notnull())
233
if (field_arg->def == NULL && attribute->constraints().is_nullable())
273
235
message::Table::Field::FieldOptions *field_options;
274
236
field_options= attribute->mutable_options();
297
259
< default_value->length()))
299
261
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
265
if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
339
266
&& field_arg->charset==&my_charset_bin)
340
267
|| (field_arg->sql_type==DRIZZLE_TYPE_BLOB
365
292
if (create_info->table_options & HA_OPTION_PACK_RECORD)
366
293
table_options->set_pack_record(true);
368
if (table_options->has_comment() && table_options->comment().length() == 0)
369
table_options->clear_comment();
371
295
if (table_options->has_comment())
373
297
uint32_t tmp_len;
382
306
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
383
307
table_options->comment().c_str(),"Table COMMENT",
384
308
(uint32_t) TABLE_COMMENT_MAXLEN);
389
313
if (create_info->default_table_charset)
391
table_options->set_collation_id(create_info->default_table_charset->number);
315
table_options->set_collation_id(
316
create_info->default_table_charset->number);
392
317
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
320
if (create_info->auto_increment_value)
401
321
table_options->set_auto_increment_value(create_info->auto_increment_value);
478
398
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
479
399
key_info[i].comment.str,"Index COMMENT",
480
400
(uint32_t) TABLE_COMMENT_MAXLEN);
484
404
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)
406
if (key_info[i].flags &
407
~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE |
408
HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY |
409
HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
495
410
abort(); // Invalid (unknown) index flag.
497
412
for(unsigned int j=0; j< key_info[i].key_parts; j++)
499
414
message::Table::Index::IndexPart *idxpart;
500
const int fieldnr= key_info[i].key_part[j].fieldnr;
503
416
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);
418
idxpart->set_fieldnr(key_info[i].key_part[j].fieldnr);
420
idxpart->set_compare_length(key_info[i].key_part[j].length);
526
424
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());
426
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table_proto.InitializationErrorString().c_str());
548
443
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
549
table_proto.name().c_str(),
550
table_proto.InitializationErrorString().c_str());
444
table_proto.InitializationErrorString().empty() ? "": table_proto.InitializationErrorString().c_str());
578
472
bool rea_create_table(Session *session,
579
const identifier::Table &identifier,
473
TableIdentifier &identifier,
580
474
message::Table &table_proto,
581
475
HA_CREATE_INFO *create_info,
582
476
List<CreateField> &create_fields,
583
477
uint32_t keys, KeyInfo *key_info)
585
assert(table_proto.has_name());
586
if (fill_table_proto(table_proto, create_fields, create_info,
479
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,
483
if (plugin::StorageEngine::createTable(*session,