75
75
/*************************************************************************/
77
/* Get column name from column hash */
79
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
81
*length= (uint32_t) strlen((*buff)->field_name);
82
return (unsigned char*) (*buff)->field_name;
86
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
88
enum_field_types field_type;
90
switch(proto_field_type)
92
case message::Table::Field::INTEGER:
93
field_type= DRIZZLE_TYPE_LONG;
95
case message::Table::Field::DOUBLE:
96
field_type= DRIZZLE_TYPE_DOUBLE;
98
case message::Table::Field::TIMESTAMP:
99
field_type= DRIZZLE_TYPE_TIMESTAMP;
101
case message::Table::Field::BIGINT:
102
field_type= DRIZZLE_TYPE_LONGLONG;
104
case message::Table::Field::DATETIME:
105
field_type= DRIZZLE_TYPE_DATETIME;
107
case message::Table::Field::DATE:
108
field_type= DRIZZLE_TYPE_DATE;
110
case message::Table::Field::VARCHAR:
111
field_type= DRIZZLE_TYPE_VARCHAR;
113
case message::Table::Field::DECIMAL:
114
field_type= DRIZZLE_TYPE_DECIMAL;
116
case message::Table::Field::ENUM:
117
field_type= DRIZZLE_TYPE_ENUM;
119
case message::Table::Field::BLOB:
120
field_type= DRIZZLE_TYPE_BLOB;
123
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
130
static Item *default_value_item(enum_field_types field_type,
131
const CHARSET_INFO *charset,
132
bool default_null, const string *default_value,
133
const string *default_bin_value)
135
Item *default_item= NULL;
140
return new Item_null();
145
case DRIZZLE_TYPE_LONG:
146
case DRIZZLE_TYPE_LONGLONG:
147
default_item= new Item_int(default_value->c_str(),
148
(int64_t) internal::my_strtoll10(default_value->c_str(),
151
default_value->length());
153
case DRIZZLE_TYPE_DOUBLE:
154
default_item= new Item_float(default_value->c_str(),
155
default_value->length());
157
case DRIZZLE_TYPE_NULL:
159
case DRIZZLE_TYPE_TIMESTAMP:
160
case DRIZZLE_TYPE_DATETIME:
161
case DRIZZLE_TYPE_DATE:
162
if (default_value->compare("NOW()") == 0)
164
case DRIZZLE_TYPE_ENUM:
165
default_item= new Item_string(default_value->c_str(),
166
default_value->length(),
167
system_charset_info);
169
case DRIZZLE_TYPE_VARCHAR:
170
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
171
if (charset==&my_charset_bin)
173
default_item= new Item_string(default_bin_value->c_str(),
174
default_bin_value->length(),
179
default_item= new Item_string(default_value->c_str(),
180
default_value->length(),
181
system_charset_info);
184
case DRIZZLE_TYPE_DECIMAL:
185
default_item= new Item_decimal(default_value->c_str(),
186
default_value->length(),
187
system_charset_info);
194
int TableShare::inner_parse_table_proto(Session& session, message::Table &table)
196
TableShare *share= this;
199
if (! table.IsInitialized())
201
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
202
return ER_CORRUPT_TABLE_DEFINITION;
205
share->setTableProto(new(nothrow) message::Table(table));
207
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
208
assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
210
message::Table::TableOptions table_options;
212
if (table.has_options())
213
table_options= table.options();
215
uint32_t local_db_create_options= 0;
217
if (table_options.pack_record())
218
local_db_create_options|= HA_OPTION_PACK_RECORD;
220
/* local_db_create_options was stored as 2 bytes in FRM
221
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
223
share->db_create_options= (local_db_create_options & 0x0000FFFF);
224
share->db_options_in_use= share->db_create_options;
226
share->row_type= table_options.has_row_type() ?
227
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
229
share->block_size= table_options.has_block_size() ?
230
table_options.block_size() : 0;
232
share->table_charset= get_charset(table_options.has_collation_id()?
233
table_options.collation_id() : 0);
235
if (!share->table_charset)
237
/* unknown charset in head[38] or pre-3.23 frm */
238
if (use_mb(default_charset_info))
240
/* Warn that we may be changing the size of character columns */
241
errmsg_printf(ERRMSG_LVL_WARN,
242
_("'%s' had no or invalid character set, "
243
"and default character set is multi-byte, "
244
"so character column sizes may have changed"),
247
share->table_charset= default_charset_info;
250
share->db_record_offset= 1;
252
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
254
share->keys= table.indexes_size();
257
for (int indx= 0; indx < table.indexes_size(); indx++)
258
share->key_parts+= table.indexes(indx).index_part_size();
260
share->key_info= (KEY*) share->alloc_root( table.indexes_size() * sizeof(KEY) +share->key_parts*sizeof(KEY_PART_INFO));
262
KEY_PART_INFO *key_part;
264
key_part= reinterpret_cast<KEY_PART_INFO*>
265
(share->key_info+table.indexes_size());
268
ulong *rec_per_key= (ulong*) share->alloc_root(sizeof(ulong*)*share->key_parts);
270
share->keynames.count= table.indexes_size();
271
share->keynames.name= NULL;
272
share->keynames.type_names= (const char**)
273
share->alloc_root(sizeof(char*) * (table.indexes_size()+1));
275
share->keynames.type_lengths= (unsigned int*)
276
share->alloc_root(sizeof(unsigned int) * (table.indexes_size()+1));
278
share->keynames.type_names[share->keynames.count]= NULL;
279
share->keynames.type_lengths[share->keynames.count]= 0;
281
KEY* keyinfo= share->key_info;
282
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
284
message::Table::Index indx= table.indexes(keynr);
289
if (indx.is_unique())
290
keyinfo->flags|= HA_NOSAME;
292
if (indx.has_options())
294
message::Table::Index::IndexOptions indx_options= indx.options();
295
if (indx_options.pack_key())
296
keyinfo->flags|= HA_PACK_KEY;
298
if (indx_options.var_length_key())
299
keyinfo->flags|= HA_VAR_LENGTH_PART;
301
if (indx_options.null_part_key())
302
keyinfo->flags|= HA_NULL_PART_KEY;
304
if (indx_options.binary_pack_key())
305
keyinfo->flags|= HA_BINARY_PACK_KEY;
307
if (indx_options.has_partial_segments())
308
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
310
if (indx_options.auto_generated_key())
311
keyinfo->flags|= HA_GENERATED_KEY;
313
if (indx_options.has_key_block_size())
315
keyinfo->flags|= HA_USES_BLOCK_SIZE;
316
keyinfo->block_size= indx_options.key_block_size();
320
keyinfo->block_size= 0;
326
case message::Table::Index::UNKNOWN_INDEX:
327
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
329
case message::Table::Index::BTREE:
330
keyinfo->algorithm= HA_KEY_ALG_BTREE;
332
case message::Table::Index::HASH:
333
keyinfo->algorithm= HA_KEY_ALG_HASH;
337
/* TODO: suitable warning ? */
338
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
342
keyinfo->key_length= indx.key_length();
344
keyinfo->key_parts= indx.index_part_size();
346
keyinfo->key_part= key_part;
347
keyinfo->rec_per_key= rec_per_key;
349
for (unsigned int partnr= 0;
350
partnr < keyinfo->key_parts;
351
partnr++, key_part++)
353
message::Table::Index::IndexPart part;
354
part= indx.index_part(partnr);
358
key_part->field= NULL;
359
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
360
key_part->null_bit= 0;
361
/* key_part->null_offset is only set if null_bit (see later) */
362
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
363
/* key_part->type ???? */
364
key_part->key_part_flag= 0;
365
if (part.has_in_reverse_order())
366
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
368
key_part->length= part.compare_length();
370
key_part->store_length= key_part->length;
372
/* key_part->offset is set later */
373
key_part->key_type= part.key_type();
376
if (! indx.has_comment())
378
keyinfo->comment.length= 0;
379
keyinfo->comment.str= NULL;
383
keyinfo->flags|= HA_USES_COMMENT;
384
keyinfo->comment.length= indx.comment().length();
385
keyinfo->comment.str= share->strmake_root(indx.comment().c_str(), keyinfo->comment.length);
388
keyinfo->name= share->strmake_root(indx.name().c_str(), indx.name().length());
390
share->keynames.type_names[keynr]= keyinfo->name;
391
share->keynames.type_lengths[keynr]= indx.name().length();
394
share->keys_for_keyread.reset();
395
set_prefix(share->keys_in_use, share->keys);
397
share->fields= table.field_size();
399
share->field= (Field**) share->alloc_root(((share->fields+1) * sizeof(Field*)));
400
share->field[share->fields]= NULL;
402
uint32_t local_null_fields= 0;
405
vector<uint32_t> field_offsets;
406
vector<uint32_t> field_pack_length;
408
field_offsets.resize(share->fields);
409
field_pack_length.resize(share->fields);
411
uint32_t interval_count= 0;
412
uint32_t interval_parts= 0;
414
uint32_t stored_columns_reclength= 0;
416
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
418
message::Table::Field pfield= table.field(fieldnr);
419
if (pfield.constraints().is_nullable())
422
enum_field_types drizzle_field_type=
423
proto_field_type_to_drizzle_type(pfield.type());
425
field_offsets[fieldnr]= stored_columns_reclength;
427
/* the below switch is very similar to
428
CreateField::create_length_to_internal_length in field.cc
429
(which should one day be replace by just this code)
431
switch(drizzle_field_type)
433
case DRIZZLE_TYPE_BLOB:
434
case DRIZZLE_TYPE_VARCHAR:
436
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
438
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
439
field_options.collation_id() : 0);
442
cs= default_charset_info;
444
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
445
field_options.length() * cs->mbmaxlen);
448
case DRIZZLE_TYPE_ENUM:
450
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
452
field_pack_length[fieldnr]=
453
get_enum_pack_length(field_options.field_value_size());
456
interval_parts+= field_options.field_value_size();
459
case DRIZZLE_TYPE_DECIMAL:
461
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
463
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
467
/* Zero is okay here as length is fixed for other types. */
468
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
471
share->reclength+= field_pack_length[fieldnr];
472
stored_columns_reclength+= field_pack_length[fieldnr];
475
/* data_offset added to stored_rec_length later */
476
share->stored_rec_length= stored_columns_reclength;
478
share->null_fields= local_null_fields;
480
ulong null_bits= local_null_fields;
481
if (! table_options.pack_record())
483
ulong data_offset= (null_bits + 7)/8;
486
share->reclength+= data_offset;
487
share->stored_rec_length+= data_offset;
489
ulong local_rec_buff_length;
491
local_rec_buff_length= ALIGN_SIZE(share->reclength + 1);
492
share->rec_buff_length= local_rec_buff_length;
494
unsigned char* record= NULL;
496
if (! (record= (unsigned char *) share->alloc_root(local_rec_buff_length)))
499
memset(record, 0, local_rec_buff_length);
503
if (! table_options.pack_record())
505
null_count++; // one bit for delete mark.
509
share->default_values= record;
513
share->intervals= (TYPELIB *) share->alloc_root(interval_count*sizeof(TYPELIB));
517
share->intervals= NULL;
520
share->fieldnames.type_names= (const char **) share->alloc_root((share->fields + 1) * sizeof(char*));
522
share->fieldnames.type_lengths= (unsigned int *) share->alloc_root((share->fields + 1) * sizeof(unsigned int));
524
share->fieldnames.type_names[share->fields]= NULL;
525
share->fieldnames.type_lengths[share->fields]= 0;
526
share->fieldnames.count= share->fields;
529
/* Now fix the TYPELIBs for the intervals (enum values)
533
uint32_t interval_nr= 0;
535
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
537
message::Table::Field pfield= table.field(fieldnr);
540
share->fieldnames.type_names[fieldnr]= share->strmake_root(pfield.name().c_str(), pfield.name().length());
542
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
545
if (pfield.type() != message::Table::Field::ENUM)
548
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
550
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
551
field_options.collation_id() : 0);
554
charset= default_charset_info;
556
TYPELIB *t= &(share->intervals[interval_nr]);
558
t->type_names= (const char**)share->alloc_root((field_options.field_value_size() + 1) * sizeof(char*));
560
t->type_lengths= (unsigned int*) share->alloc_root((field_options.field_value_size() + 1) * sizeof(unsigned int));
562
t->type_names[field_options.field_value_size()]= NULL;
563
t->type_lengths[field_options.field_value_size()]= 0;
565
t->count= field_options.field_value_size();
568
for (int n= 0; n < field_options.field_value_size(); n++)
570
t->type_names[n]= share->strmake_root(field_options.field_value(n).c_str(), field_options.field_value(n).length());
573
* Go ask the charset what the length is as for "" length=1
574
* and there's stripping spaces or some other crack going on.
577
lengthsp= charset->cset->lengthsp(charset,
579
field_options.field_value(n).length());
580
t->type_lengths[n]= lengthsp;
586
/* and read the fields */
589
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
592
use_hash= ! hash_init(&share->name_hash,
597
(hash_get_key) get_field_name,
601
unsigned char* null_pos= record;;
602
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
604
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
606
message::Table::Field pfield= table.field(fieldnr);
608
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
610
switch (pfield.format())
612
case message::Table::Field::DefaultFormat:
613
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
615
case message::Table::Field::FixedFormat:
616
column_format= COLUMN_FORMAT_TYPE_FIXED;
618
case message::Table::Field::DynamicFormat:
619
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
625
Field::utype unireg_type= Field::NONE;
627
if (pfield.has_numeric_options() &&
628
pfield.numeric_options().is_autoincrement())
630
unireg_type= Field::NEXT_NUMBER;
633
if (pfield.has_options() &&
634
pfield.options().has_default_value() &&
635
pfield.options().default_value().compare("NOW()") == 0)
637
if (pfield.options().has_update_value() &&
638
pfield.options().update_value().compare("NOW()") == 0)
640
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
642
else if (! pfield.options().has_update_value())
644
unireg_type= Field::TIMESTAMP_DN_FIELD;
647
assert(1); // Invalid update value.
649
else if (pfield.has_options() &&
650
pfield.options().has_update_value() &&
651
pfield.options().update_value().compare("NOW()") == 0)
653
unireg_type= Field::TIMESTAMP_UN_FIELD;
657
if (!pfield.has_comment())
659
comment.str= (char*)"";
664
size_t len= pfield.comment().length();
665
const char* str= pfield.comment().c_str();
667
comment.str= share->strmake_root(str, len);
671
enum_field_types field_type;
673
field_type= proto_field_type_to_drizzle_type(pfield.type());
675
const CHARSET_INFO *charset= &my_charset_bin;
677
if (field_type == DRIZZLE_TYPE_BLOB ||
678
field_type == DRIZZLE_TYPE_VARCHAR)
680
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
682
charset= get_charset(field_options.has_collation_id() ?
683
field_options.collation_id() : 0);
686
charset= default_charset_info;
689
if (field_type == DRIZZLE_TYPE_ENUM)
691
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
693
charset= get_charset(field_options.has_collation_id()?
694
field_options.collation_id() : 0);
697
charset= default_charset_info;
701
if (field_type == DRIZZLE_TYPE_DECIMAL
702
|| field_type == DRIZZLE_TYPE_DOUBLE)
704
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
706
if (! pfield.has_numeric_options() || ! fo.has_scale())
709
We don't write the default to table proto so
710
if no decimals specified for DOUBLE, we use the default.
712
decimals= NOT_FIXED_DEC;
716
if (fo.scale() > DECIMAL_MAX_SCALE)
722
decimals= static_cast<uint8_t>(fo.scale());
726
Item *default_value= NULL;
728
if (pfield.options().has_default_value() ||
729
pfield.options().has_default_null() ||
730
pfield.options().has_default_bin_value())
732
default_value= default_value_item(field_type,
734
pfield.options().default_null(),
735
&pfield.options().default_value(),
736
&pfield.options().default_bin_value());
740
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
741
memset(&temp_table, 0, sizeof(temp_table));
743
temp_table.in_use= &session;
744
temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
745
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
747
uint32_t field_length= 0; //Assignment is for compiler complaint.
751
case DRIZZLE_TYPE_BLOB:
752
case DRIZZLE_TYPE_VARCHAR:
754
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
756
charset= get_charset(field_options.has_collation_id() ?
757
field_options.collation_id() : 0);
760
charset= default_charset_info;
762
field_length= field_options.length() * charset->mbmaxlen;
765
case DRIZZLE_TYPE_DOUBLE:
767
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
768
if (!fo.has_precision() && !fo.has_scale())
770
field_length= DBL_DIG+7;
774
field_length= fo.precision();
776
if (field_length < decimals &&
777
decimals != NOT_FIXED_DEC)
779
my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
786
case DRIZZLE_TYPE_DECIMAL:
788
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
790
field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
794
case DRIZZLE_TYPE_TIMESTAMP:
795
case DRIZZLE_TYPE_DATETIME:
796
field_length= DateTime::MAX_STRING_LENGTH;
798
case DRIZZLE_TYPE_DATE:
799
field_length= Date::MAX_STRING_LENGTH;
801
case DRIZZLE_TYPE_ENUM:
805
message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
807
for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
809
if (fo.field_value(valnr).length() > field_length)
811
field_length= charset->cset->numchars(charset,
812
fo.field_value(valnr).c_str(),
813
fo.field_value(valnr).c_str()
814
+ fo.field_value(valnr).length())
820
case DRIZZLE_TYPE_LONG:
822
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
823
field_length= MAX_INT_WIDTH+sign_len;
826
case DRIZZLE_TYPE_LONGLONG:
827
field_length= MAX_BIGINT_WIDTH;
829
case DRIZZLE_TYPE_NULL:
830
abort(); // Programming error
833
Field* f= share->make_field(record + field_offsets[fieldnr] + data_offset,
835
pfield.constraints().is_nullable(),
841
(Field::utype) MTYP_TYPENR(unireg_type),
842
((field_type == DRIZZLE_TYPE_ENUM) ?
843
share->intervals + (interval_nr++)
845
share->fieldnames.type_names[fieldnr]);
847
share->field[fieldnr]= f;
849
f->init(&temp_table); /* blob default values need table obj */
851
if (! (f->flags & NOT_NULL_FLAG))
853
*f->null_ptr|= f->null_bit;
854
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
861
enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
862
session.count_cuted_fields= CHECK_FIELD_WARN;
863
int res= default_value->save_in_field(f, 1);
864
session.count_cuted_fields= old_count_cuted_fields;
865
if (res != 0 && res != 3) /* @TODO Huh? */
867
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
873
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
874
(f->flags & NOT_NULL_FLAG))
877
f->store((int64_t) 1, true);
884
/* hack to undo f->init() */
888
f->field_index= fieldnr;
890
if (! default_value &&
891
! (f->unireg_check==Field::NEXT_NUMBER) &&
892
(f->flags & NOT_NULL_FLAG) &&
893
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
895
f->flags|= NO_DEFAULT_VALUE_FLAG;
898
if (f->unireg_check == Field::NEXT_NUMBER)
899
share->found_next_number_field= &(share->field[fieldnr]);
901
if (share->timestamp_field == f)
902
share->timestamp_field_offset= fieldnr;
904
if (use_hash) /* supposedly this never fails... but comments lie */
905
(void) my_hash_insert(&share->name_hash,
906
(unsigned char*)&(share->field[fieldnr]));
910
keyinfo= share->key_info;
911
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
913
key_part= keyinfo->key_part;
915
for (unsigned int partnr= 0;
916
partnr < keyinfo->key_parts;
917
partnr++, key_part++)
920
* Fix up key_part->offset by adding data_offset.
921
* We really should compute offset as well.
922
* But at least this way we are a little better.
924
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
929
We need to set the unused bits to 1. If the number of bits is a multiple
930
of 8 there are no unused bits.
934
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
936
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
938
share->last_null_bit_pos= null_bit_pos;
941
if (share->key_parts)
943
uint32_t local_primary_key= (uint32_t) (find_type((char*) "PRIMARY",
944
&share->keynames, 3) - 1); /* @TODO Huh? */
946
keyinfo= share->key_info;
947
key_part= keyinfo->key_part;
949
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
951
uint32_t usable_parts= 0;
953
if (local_primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
956
If the UNIQUE key doesn't have NULL columns and is not a part key
957
declare this as a primary key.
959
local_primary_key=key;
960
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
962
uint32_t fieldnr= key_part[i].fieldnr;
964
share->field[fieldnr-1]->null_ptr ||
965
share->field[fieldnr-1]->key_length() != key_part[i].length)
967
local_primary_key= MAX_KEY; // Can't be used
973
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
976
if (! key_part->fieldnr)
980
local_field= key_part->field= share->field[key_part->fieldnr-1];
981
key_part->type= local_field->key_type();
982
if (local_field->null_ptr)
984
key_part->null_offset=(uint32_t) ((unsigned char*) local_field->null_ptr - share->default_values);
985
key_part->null_bit= local_field->null_bit;
986
key_part->store_length+=HA_KEY_NULL_LENGTH;
987
keyinfo->flags|=HA_NULL_PART_KEY;
988
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
989
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
991
if (local_field->type() == DRIZZLE_TYPE_BLOB ||
992
local_field->real_type() == DRIZZLE_TYPE_VARCHAR)
994
if (local_field->type() == DRIZZLE_TYPE_BLOB)
995
key_part->key_part_flag|= HA_BLOB_PART;
997
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
998
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
999
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1000
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1002
if (i == 0 && key != local_primary_key)
1003
local_field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1004
(keyinfo->key_parts == 1)) ?
1005
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1007
local_field->key_start.set(key);
1008
if (local_field->key_length() == key_part->length &&
1009
!(local_field->flags & BLOB_FLAG))
1011
enum ha_key_alg algo= share->key_info[key].algorithm;
1012
if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1014
share->keys_for_keyread.set(key);
1015
local_field->part_of_key.set(key);
1016
local_field->part_of_key_not_clustered.set(key);
1018
if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1019
local_field->part_of_sortkey.set(key);
1021
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1023
usable_parts++; // For FILESORT
1024
local_field->flags|= PART_KEY_FLAG;
1025
if (key == local_primary_key)
1027
local_field->flags|= PRI_KEY_FLAG;
1029
If this field is part of the primary key and all keys contains
1030
the primary key, then we can use any key to find this column
1032
if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1034
local_field->part_of_key= share->keys_in_use;
1035
if (local_field->part_of_sortkey.test(key))
1036
local_field->part_of_sortkey= share->keys_in_use;
1039
if (local_field->key_length() != key_part->length)
1041
key_part->key_part_flag|= HA_PART_KEY_SEG;
1044
keyinfo->usable_key_parts= usable_parts; // Filesort
1046
set_if_bigger(share->max_key_length,keyinfo->key_length+
1047
keyinfo->key_parts);
1048
share->total_key_length+= keyinfo->key_length;
1050
if (keyinfo->flags & HA_NOSAME)
1052
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1055
if (local_primary_key < MAX_KEY &&
1056
(share->keys_in_use.test(local_primary_key)))
1058
share->primary_key= local_primary_key;
1060
If we are using an integer as the primary key then allow the user to
1061
refer to it as '_rowid'
1063
if (share->key_info[local_primary_key].key_parts == 1)
1065
Field *local_field= share->key_info[local_primary_key].key_part[0].field;
1066
if (local_field && local_field->result_type() == INT_RESULT)
1068
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1069
share->rowid_field_offset= (share->key_info[local_primary_key].key_part[0].
1076
share->primary_key = MAX_KEY; // we do not have a primary key
1081
share->primary_key= MAX_KEY;
1084
if (share->found_next_number_field)
1086
Field *reg_field= *share->found_next_number_field;
1087
if ((int) (share->next_number_index= (uint32_t)
1088
find_ref_key(share->key_info, share->keys,
1089
share->default_values, reg_field,
1090
&share->next_number_key_offset,
1091
&share->next_number_keypart)) < 0)
1093
/* Wrong field definition */
1100
reg_field->flags |= AUTO_INCREMENT_FLAG;
1104
if (share->blob_fields)
1109
/* Store offsets to blob fields to find them fast */
1110
if (!(share->blob_field= save=
1111
(uint*) share->alloc_root((uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1115
for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1117
if ((*ptr)->flags & BLOB_FLAG)
1122
share->db_low_byte_first= true; // @todo Question this.
1123
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1125
my_bitmap_map *bitmaps;
1127
if (!(bitmaps= (my_bitmap_map*) share->alloc_root(share->column_bitmap_size)))
1131
share->all_set.init(bitmaps, share->fields);
1132
share->all_set.setAll();
1140
int TableShare::parse_table_proto(Session& session, message::Table &table)
1142
int local_error= inner_parse_table_proto(session, table);
1144
if (not local_error)
1150
hash_free(&name_hash);
1151
open_table_error(local_error, open_errno, 0);
1158
Read table definition from a binary / text based .frm cursor
1162
session Thread Cursor
1163
share Fill this with table definition
1166
This function is called when the table definition is not cached in
1168
The data is returned in 'share', which is alloced by
1169
alloc_table_share().. The code assumes that share is initialized.
1173
1 Error (see open_table_error)
1174
2 Error (see open_table_error)
1175
3 Wrong data in .frm cursor
1176
4 Error (see open_table_error)
1177
5 Error (see open_table_error: charset unavailable)
1178
6 Unknown .frm version
1181
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1189
message::Table table;
1191
local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1193
if (local_error != EEXIST)
1195
if (local_error > 0)
1202
if (not table.IsInitialized())
1210
local_error= parse_table_proto(session, table);
1212
setTableCategory(TABLE_CATEGORY_USER);
1215
if (local_error && !error_given)
1218
open_table_error(error, (open_errno= errno), 0);
1226
Open a table based on a TableShare
1229
open_table_from_share()
1230
session Thread Cursor
1231
share Table definition
1232
alias Alias for table
1233
db_stat open flags (for example HA_OPEN_KEYFILE|
1234
HA_OPEN_RNDFILE..) can be 0 (example in
1236
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1237
outparam result table
1241
1 Error (see open_table_error)
1242
2 Error (see open_table_error)
1243
3 Wrong data in .frm cursor
1244
4 Error (see open_table_error)
1245
5 Error (see open_table_error: charset unavailable)
1246
7 Table definition has changed in engine
1249
int TableShare::open_table_from_share(Session *session, const char *alias,
1250
uint32_t db_stat, uint32_t ha_open_flags,
1254
uint32_t records, bitmap_size;
1255
bool error_reported= false;
1256
unsigned char *record, *bitmaps;
1259
/* Parsing of partitioning information from .frm needs session->lex set up. */
1260
assert(session->lex->is_lex_started);
1263
outparam.resetTable(session, this, db_stat);
1266
if (not (outparam.alias= strdup(alias)))
1269
/* Allocate Cursor */
1270
if (not (outparam.cursor= db_type()->getCursor(*this, &outparam.mem_root)))
1275
if ((db_stat & HA_OPEN_KEYFILE))
1280
if (!(record= (unsigned char*) outparam.mem_root.alloc_root(rec_buff_length * records)))
1285
/* We are probably in hard repair, and the buffers should not be used */
1286
outparam.record[0]= outparam.record[1]= default_values;
1290
outparam.record[0]= record;
1292
outparam.record[1]= record+ rec_buff_length;
1294
outparam.record[1]= outparam.record[0]; // Safety
1299
We need this because when we read var-length rows, we are not updating
1300
bytes after end of varchar
1304
memcpy(outparam.record[0], default_values, rec_buff_length);
1305
memcpy(outparam.record[1], default_values, null_bytes);
1307
memcpy(outparam.record[1], default_values, rec_buff_length);
1312
memcpy(outparam.record[1], default_values, null_bytes);
1315
if (!(field_ptr = (Field **) outparam.mem_root.alloc_root( (uint32_t) ((fields+1)* sizeof(Field*)))))
1320
outparam.field= field_ptr;
1322
record= (unsigned char*) outparam.record[0]-1; /* Fieldstart = 1 */
1324
outparam.null_flags= (unsigned char*) record+1;
1326
/* Setup copy of fields from share, but use the right alias and record */
1327
for (uint32_t i= 0 ; i < fields; i++, field_ptr++)
1329
if (!((*field_ptr)= field[i]->clone(&outparam.mem_root, &outparam)))
1332
(*field_ptr)= 0; // End marker
1334
if (found_next_number_field)
1335
outparam.found_next_number_field=
1336
outparam.field[(uint32_t) (found_next_number_field - field)];
1337
if (timestamp_field)
1338
outparam.timestamp_field= (Field_timestamp*) outparam.field[timestamp_field_offset];
1341
/* Fix key->name and key_part->field */
1344
KEY *local_key_info, *key_info_end;
1345
KEY_PART_INFO *key_part;
1347
n_length= keys*sizeof(KEY) + key_parts*sizeof(KEY_PART_INFO);
1348
if (!(local_key_info= (KEY*) outparam.mem_root.alloc_root(n_length)))
1350
outparam.key_info= local_key_info;
1351
key_part= (reinterpret_cast<KEY_PART_INFO*> (local_key_info+keys));
1353
memcpy(local_key_info, key_info, sizeof(*local_key_info)*keys);
1354
memcpy(key_part, key_info[0].key_part, (sizeof(*key_part) *
1357
for (key_info_end= local_key_info + keys ;
1358
local_key_info < key_info_end ;
1361
KEY_PART_INFO *key_part_end;
1363
local_key_info->table= &outparam;
1364
local_key_info->key_part= key_part;
1366
for (key_part_end= key_part+ local_key_info->key_parts ;
1367
key_part < key_part_end ;
1370
Field *local_field= key_part->field= outparam.field[key_part->fieldnr-1];
1372
if (local_field->key_length() != key_part->length &&
1373
!(local_field->flags & BLOB_FLAG))
1376
We are using only a prefix of the column as a key:
1377
Create a new field for the key part that matches the index
1379
local_field= key_part->field= local_field->new_field(&outparam.mem_root, &outparam, 0);
1380
local_field->field_length= key_part->length;
1386
/* Allocate bitmaps */
1388
bitmap_size= column_bitmap_size;
1389
if (!(bitmaps= (unsigned char*) outparam.mem_root.alloc_root(bitmap_size*3)))
1393
outparam.def_read_set.init((my_bitmap_map*) bitmaps, fields);
1394
outparam.def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), fields);
1395
outparam.tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), fields);
1396
outparam.default_column_bitmaps();
1398
/* The table struct is now initialized; Open the table */
1403
if ((ha_err= (outparam.cursor->
1404
ha_open(&outparam, getNormalizedPath(),
1405
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1406
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1407
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1408
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1409
HA_OPEN_ABORT_IF_LOCKED :
1410
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1414
case HA_ERR_NO_SUCH_TABLE:
1416
The table did not exists in storage engine, use same error message
1417
as if the .frm cursor didn't exist
1424
Too many files opened, use same error message as if the .frm
1431
outparam.print_error(ha_err, MYF(0));
1432
error_reported= true;
1433
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1441
#if defined(HAVE_purify)
1442
memset(bitmaps, 0, bitmap_size*3);
1448
if (!error_reported)
1449
open_table_error(local_error, errno, 0);
1451
delete outparam.cursor;
1452
outparam.cursor= 0; // For easier error checking
1453
outparam.db_stat= 0;
1454
outparam.mem_root.free_root(MYF(0)); // Safe to call on zeroed root
1455
free((char*) outparam.alias);
1456
return (local_error);
1459
bool Table::fill_item_list(List<Item> *item_list) const
1462
All Item_field's created using a direct pointer to a field
1463
are fixed in Item_field constructor.
1465
for (Field **ptr= field; *ptr; ptr++)
1467
Item_field *item= new Item_field(*ptr);
1468
if (!item || item_list->push_back(item))
1474
77
// @note this should all be the destructor
1475
78
int Table::delete_table(bool free_share)