13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include <drizzled/server_includes.h>
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/internal/my_sys.h"
31
24
#include <drizzled/message/schema.pb.h>
32
25
#include <drizzled/message/table.pb.h>
33
26
#include <google/protobuf/io/zero_copy_stream.h>
34
27
#include <google/protobuf/io/zero_copy_stream_impl.h>
36
29
#include <drizzled/table_proto.h>
38
30
using namespace std;
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,
32
int fill_table_proto(drizzled::message::Table *table_proto,
33
const char *table_name,
34
List<CreateField> &create_fields,
35
HA_CREATE_INFO *create_info,
49
39
CreateField *field_arg;
50
40
List_iterator<CreateField> it(create_fields);
51
message::Table::TableOptions *table_options= table_proto.mutable_options();
41
drizzled::message::Table::TableOptions *table_options= table_proto->mutable_options();
53
43
if (create_fields.elements > MAX_FIELDS)
59
assert(strcmp(table_proto.engine().name().c_str(),
49
assert(strcmp(table_proto->engine().name().c_str(),
60
50
create_info->db_type->getName().c_str())==0);
62
assert(table_proto.name() == table_name);
52
assert(strcmp(table_proto->name().c_str(),table_name)==0);
65
bool use_existing_fields= table_proto.field_size() > 0;
66
54
while ((field_arg= it++))
68
message::Table::Field *attribute;
70
/* some (one) code path for CREATE TABLE fills the proto
71
out more than the others, so we already have partially
72
filled out Field messages */
74
if (use_existing_fields)
75
attribute= table_proto.mutable_field(field_number++);
56
drizzled::message::Table::Field *attribute;
58
attribute= table_proto->add_field();
59
attribute->set_name(field_arg->field_name);
61
attribute->set_pack_flag(field_arg->pack_flag); /* TODO: MUST DIE */
63
if(f_maybe_null(field_arg->pack_flag))
78
/* Other code paths still have to fill out the proto */
79
attribute= table_proto.add_field();
81
if (field_arg->flags & NOT_NULL_FLAG)
83
message::Table::Field::FieldConstraints *constraints;
85
constraints= attribute->mutable_constraints();
86
constraints->set_is_nullable(false);
89
attribute->set_name(field_arg->field_name);
65
drizzled::message::Table::Field::FieldConstraints *constraints;
67
constraints= attribute->mutable_constraints();
68
constraints->set_is_nullable(true);
92
assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
93
assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
96
message::Table::Field::FieldType parser_type= attribute->type();
98
attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
100
switch (attribute->type()) {
101
default: /* Only deal with types that need extra information */
103
case message::Table::Field::DOUBLE:
106
* For DOUBLE, we only add a specific scale and precision iff
107
* the fixed decimal point has been specified...
109
if (field_arg->decimals != NOT_FIXED_DEC)
111
message::Table::Field::NumericFieldOptions *numeric_field_options;
113
numeric_field_options= attribute->mutable_numeric_options();
115
numeric_field_options->set_precision(field_arg->length);
116
numeric_field_options->set_scale(field_arg->decimals);
120
case message::Table::Field::VARCHAR:
122
message::Table::Field::StringFieldOptions *string_field_options;
71
switch (field_arg->sql_type) {
72
case DRIZZLE_TYPE_TINY:
73
attribute->set_type(drizzled::message::Table::Field::TINYINT);
75
case DRIZZLE_TYPE_LONG:
76
attribute->set_type(drizzled::message::Table::Field::INTEGER);
78
case DRIZZLE_TYPE_DOUBLE:
79
attribute->set_type(drizzled::message::Table::Field::DOUBLE);
81
case DRIZZLE_TYPE_NULL :
82
assert(1); /* Not a user definable type */
83
case DRIZZLE_TYPE_TIMESTAMP:
84
attribute->set_type(drizzled::message::Table::Field::TIMESTAMP);
86
case DRIZZLE_TYPE_LONGLONG:
87
attribute->set_type(drizzled::message::Table::Field::BIGINT);
89
case DRIZZLE_TYPE_DATETIME:
90
attribute->set_type(drizzled::message::Table::Field::DATETIME);
92
case DRIZZLE_TYPE_DATE:
93
attribute->set_type(drizzled::message::Table::Field::DATE);
95
case DRIZZLE_TYPE_VARCHAR:
97
drizzled::message::Table::Field::StringFieldOptions *string_field_options;
124
99
string_field_options= attribute->mutable_string_options();
126
if (! use_existing_fields || string_field_options->length()==0)
127
string_field_options->set_length(field_arg->length
128
/ field_arg->charset->mbmaxlen);
130
assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
132
if (! string_field_options->has_collation())
134
string_field_options->set_collation_id(field_arg->charset->number);
135
string_field_options->set_collation(field_arg->charset->name);
100
attribute->set_type(drizzled::message::Table::Field::VARCHAR);
101
string_field_options->set_length(field_arg->length
102
/ field_arg->charset->mbmaxlen);
103
string_field_options->set_collation_id(field_arg->charset->number);
104
string_field_options->set_collation(field_arg->charset->name);
139
case message::Table::Field::DECIMAL:
108
case DRIZZLE_TYPE_NEWDECIMAL:
141
message::Table::Field::NumericFieldOptions *numeric_field_options;
110
drizzled::message::Table::Field::NumericFieldOptions *numeric_field_options;
112
attribute->set_type(drizzled::message::Table::Field::DECIMAL);
143
113
numeric_field_options= attribute->mutable_numeric_options();
144
114
/* This is magic, I hate magic numbers -Brian */
145
115
numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
146
116
numeric_field_options->set_scale(field_arg->decimals);
149
case message::Table::Field::ENUM:
119
case DRIZZLE_TYPE_ENUM:
151
message::Table::Field::EnumerationValues *enumeration_options;
121
drizzled::message::Table::Field::SetFieldOptions *set_field_options;
153
123
assert(field_arg->interval);
155
enumeration_options= attribute->mutable_enumeration_values();
125
attribute->set_type(drizzled::message::Table::Field::ENUM);
126
set_field_options= attribute->mutable_set_options();
157
128
for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
159
130
const char *src= field_arg->interval->type_names[pos];
161
enumeration_options->add_field_value(src);
132
set_field_options->add_field_value(src);
163
enumeration_options->set_collation_id(field_arg->charset->number);
164
enumeration_options->set_collation(field_arg->charset->name);
134
set_field_options->set_count_elements(set_field_options->field_value_size());
135
set_field_options->set_collation_id(field_arg->charset->number);
136
set_field_options->set_collation(field_arg->charset->name);
167
case message::Table::Field::BLOB:
139
case DRIZZLE_TYPE_BLOB:
169
message::Table::Field::StringFieldOptions *string_field_options;
141
attribute->set_type(drizzled::message::Table::Field::BLOB);
143
drizzled::message::Table::Field::StringFieldOptions *string_field_options;
171
145
string_field_options= attribute->mutable_string_options();
172
146
string_field_options->set_collation_id(field_arg->charset->number);
220
if (! use_existing_fields)
221
attribute->set_comment(field_arg->comment.str);
223
assert(strcmp(attribute->comment().c_str(), field_arg->comment.str)==0);
194
attribute->set_comment(field_arg->comment.str);
226
if (field_arg->unireg_check == Field::NEXT_NUMBER)
197
if(field_arg->unireg_check == Field::NEXT_NUMBER)
228
message::Table::Field::NumericFieldOptions *field_options;
199
drizzled::message::Table::Field::NumericFieldOptions *field_options;
229
200
field_options= attribute->mutable_numeric_options();
230
201
field_options->set_is_autoincrement(true);
233
if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
204
if(field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
234
205
|| field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
236
message::Table::Field::FieldOptions *field_options;
207
drizzled::message::Table::Field::FieldOptions *field_options;
237
208
field_options= attribute->mutable_options();
238
209
field_options->set_default_value("NOW()");
241
if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
212
if(field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
242
213
|| field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
244
message::Table::Field::FieldOptions *field_options;
215
drizzled::message::Table::Field::FieldOptions *field_options;
245
216
field_options= attribute->mutable_options();
246
217
field_options->set_update_value("NOW()");
249
if (field_arg->def == NULL && attribute->constraints().is_nullable())
251
message::Table::Field::FieldOptions *field_options;
222
drizzled::message::Table::Field::FieldOptions *field_options;
252
223
field_options= attribute->mutable_options();
254
field_options->set_default_null(true);
258
message::Table::Field::FieldOptions *field_options;
259
field_options= attribute->mutable_options();
261
if (field_arg->def->is_null())
225
if(field_arg->def->is_null())
263
227
field_options->set_default_null(true);
306
assert(! use_existing_fields || (field_number == table_proto.field_size()));
308
if (create_info->table_options & HA_OPTION_PACK_RECORD)
309
table_options->set_pack_record(true);
311
if (table_options->has_comment())
277
if (create_info->used_fields & HA_CREATE_USED_PACK_KEYS)
279
if(create_info->table_options & HA_OPTION_PACK_KEYS)
280
table_options->set_pack_keys(true);
281
else if(create_info->table_options & HA_OPTION_NO_PACK_KEYS)
282
table_options->set_pack_keys(false);
285
if(create_info->table_options & HA_OPTION_PACK_KEYS)
286
table_options->set_pack_keys(true);
289
if (create_info->used_fields & HA_CREATE_USED_CHECKSUM)
291
assert(create_info->table_options & (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM));
293
if(create_info->table_options & HA_OPTION_CHECKSUM)
294
table_options->set_checksum(true);
296
table_options->set_checksum(false);
298
else if(create_info->table_options & HA_OPTION_CHECKSUM)
299
table_options->set_checksum(true);
302
if (create_info->used_fields & HA_CREATE_USED_PAGE_CHECKSUM)
304
if (create_info->page_checksum == HA_CHOICE_YES)
305
table_options->set_page_checksum(true);
306
else if (create_info->page_checksum == HA_CHOICE_NO)
307
table_options->set_page_checksum(false);
309
else if (create_info->page_checksum == HA_CHOICE_YES)
310
table_options->set_page_checksum(true);
313
if (create_info->used_fields & HA_CREATE_USED_DELAY_KEY_WRITE)
315
if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
316
table_options->set_delay_key_write(true);
317
else if(create_info->table_options & HA_OPTION_NO_DELAY_KEY_WRITE)
318
table_options->set_delay_key_write(false);
320
else if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
321
table_options->set_delay_key_write(true);
324
switch(create_info->row_type)
326
case ROW_TYPE_DEFAULT:
327
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DEFAULT);
330
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_FIXED);
332
case ROW_TYPE_DYNAMIC:
333
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DYNAMIC);
335
case ROW_TYPE_COMPRESSED:
336
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPRESSED);
338
case ROW_TYPE_REDUNDANT:
339
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_REDUNDANT);
341
case ROW_TYPE_COMPACT:
342
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPACT);
345
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_PAGE);
351
table_options->set_pack_record(create_info->table_options
352
& HA_OPTION_PACK_RECORD);
354
if (create_info->comment.length)
313
356
uint32_t tmp_len;
314
357
tmp_len= system_charset_info->cset->charpos(system_charset_info,
315
table_options->comment().c_str(),
316
table_options->comment().c_str() +
317
table_options->comment().length(),
318
TABLE_COMMENT_MAXLEN);
358
create_info->comment.str,
359
create_info->comment.str +
360
create_info->comment.length,
361
TABLE_COMMENT_MAXLEN);
320
if (tmp_len < table_options->comment().length())
363
if (tmp_len < create_info->comment.length)
322
365
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
323
table_options->comment().c_str(),"Table COMMENT",
324
(uint32_t) TABLE_COMMENT_MAXLEN);
366
create_info->comment.str,"Table COMMENT",
367
(uint32_t) TABLE_COMMENT_MAXLEN);
371
table_options->set_comment(create_info->comment.str);
329
373
if (create_info->default_table_charset)
331
375
table_options->set_collation_id(
333
377
table_options->set_collation(create_info->default_table_charset->name);
380
if (create_info->connect_string.length)
381
table_options->set_connect_string(create_info->connect_string.str);
383
if (create_info->data_file_name)
384
table_options->set_data_file_name(create_info->data_file_name);
386
if (create_info->index_file_name)
387
table_options->set_index_file_name(create_info->index_file_name);
389
if (create_info->max_rows)
390
table_options->set_max_rows(create_info->max_rows);
392
if (create_info->min_rows)
393
table_options->set_min_rows(create_info->min_rows);
336
395
if (create_info->auto_increment_value)
337
396
table_options->set_auto_increment_value(create_info->auto_increment_value);
339
for (uint32_t i= 0; i < keys; i++)
398
if (create_info->avg_row_length)
399
table_options->set_avg_row_length(create_info->avg_row_length);
401
if (create_info->key_block_size)
402
table_options->set_key_block_size(create_info->key_block_size);
404
if (create_info->block_size)
405
table_options->set_block_size(create_info->block_size);
407
for (unsigned int i= 0; i < keys; i++)
341
message::Table::Index *idx;
409
drizzled::message::Table::Index *idx;
343
idx= table_proto.add_indexes();
411
idx= table_proto->add_indexes();
345
413
assert(test(key_info[i].flags & HA_USES_COMMENT) ==
346
414
(key_info[i].comment.length > 0));
378
450
idx->set_is_unique(false);
380
message::Table::Index::IndexOptions *index_options= idx->mutable_options();
452
drizzled::message::Table::Index::IndexOptions *index_options= idx->mutable_options();
382
if (key_info[i].flags & HA_USES_BLOCK_SIZE)
454
if(key_info[i].flags & HA_USES_BLOCK_SIZE)
383
455
index_options->set_key_block_size(key_info[i].block_size);
385
if (key_info[i].flags & HA_PACK_KEY)
457
if(key_info[i].flags & HA_PACK_KEY)
386
458
index_options->set_pack_key(true);
388
if (key_info[i].flags & HA_BINARY_PACK_KEY)
460
if(key_info[i].flags & HA_BINARY_PACK_KEY)
389
461
index_options->set_binary_pack_key(true);
391
if (key_info[i].flags & HA_VAR_LENGTH_PART)
463
if(key_info[i].flags & HA_VAR_LENGTH_PART)
392
464
index_options->set_var_length_key(true);
394
if (key_info[i].flags & HA_NULL_PART_KEY)
466
if(key_info[i].flags & HA_NULL_PART_KEY)
395
467
index_options->set_null_part_key(true);
397
if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
469
if(key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
398
470
index_options->set_has_partial_segments(true);
400
if (key_info[i].flags & HA_GENERATED_KEY)
472
if(key_info[i].flags & HA_GENERATED_KEY)
401
473
index_options->set_auto_generated_key(true);
403
475
if (key_info[i].flags & HA_USES_COMMENT)
515
int rename_table_proto_file(const char *from, const char* to)
517
string from_path(from);
519
string file_ext = ".dfe";
521
from_path.append(file_ext);
522
to_path.append(file_ext);
524
return my_rename(from_path.c_str(),to_path.c_str(),MYF(MY_WME));
527
int delete_table_proto_file(const char *file_name)
529
string new_path(file_name);
530
string file_ext = ".dfe";
532
new_path.append(file_ext);
533
return my_delete(new_path.c_str(), MYF(0));
536
int drizzle_write_proto_file(const std::string file_name,
537
drizzled::message::Table *table_proto)
539
int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask);
544
google::protobuf::io::ZeroCopyOutputStream* output=
545
new google::protobuf::io::FileOutputStream(fd);
547
if (table_proto->SerializeToZeroCopyStream(output) == false)
447
560
Create a table definition proto file and the tables
456
569
create_fields Fields to create
457
570
keys number of keys to create
458
571
key_info Keys to create
573
is_like is true for mysql_create_like_schema_frm
465
bool rea_create_table(Session *session,
466
TableIdentifier &identifier,
467
message::Table &table_proto,
468
HA_CREATE_INFO *create_info,
469
List<CreateField> &create_fields,
470
uint32_t keys, KEY *key_info)
580
int rea_create_table(Session *session, const char *path,
581
const char *db, const char *table_name,
582
drizzled::message::Table *table_proto,
583
HA_CREATE_INFO *create_info,
584
List<CreateField> &create_fields,
585
uint32_t keys, KEY *key_info)
472
if (fill_table_proto(table_proto, identifier.getTableName(), create_fields, create_info,
476
if (plugin::StorageEngine::createTable(*session,
587
/* Proto will blow up unless we give a name */
590
if (fill_table_proto(table_proto, table_name, create_fields, create_info,
594
string new_path(path);
595
string file_ext = ".dfe";
597
new_path.append(file_ext);
601
StorageEngine* engine= ha_resolve_by_name(session,
602
table_proto->engine().name());
603
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
604
err= drizzle_write_proto_file(new_path, table_proto);
609
my_error(ER_BAD_DB_ERROR,MYF(0),db);
611
my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,err);
616
if (ha_create_table(session, path, db, table_name,
617
create_info,0, table_proto))
622
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
623
delete_table_proto_file(path);
485
626
} /* rea_create_table */
487
} /* namespace drizzled */