558
int TableShare::inner_parse_table_proto(Session& session, message::Table &table)
560
TableShare *share= this;
563
if (! table.IsInitialized())
565
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
566
return ER_CORRUPT_TABLE_DEFINITION;
569
share->setTableProto(new(nothrow) message::Table(table));
571
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
572
assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
574
message::Table::TableOptions table_options;
576
if (table.has_options())
577
table_options= table.options();
579
uint32_t local_db_create_options= 0;
581
if (table_options.pack_record())
582
local_db_create_options|= HA_OPTION_PACK_RECORD;
584
/* local_db_create_options was stored as 2 bytes in FRM
585
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
587
share->db_create_options= (local_db_create_options & 0x0000FFFF);
588
share->db_options_in_use= share->db_create_options;
590
share->row_type= table_options.has_row_type() ?
591
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
593
share->block_size= table_options.has_block_size() ?
594
table_options.block_size() : 0;
596
share->table_charset= get_charset(table_options.has_collation_id()?
597
table_options.collation_id() : 0);
599
if (!share->table_charset)
601
/* unknown charset in head[38] or pre-3.23 frm */
602
if (use_mb(default_charset_info))
604
/* Warn that we may be changing the size of character columns */
605
errmsg_printf(ERRMSG_LVL_WARN,
606
_("'%s' had no or invalid character set, "
607
"and default character set is multi-byte, "
608
"so character column sizes may have changed"),
611
share->table_charset= default_charset_info;
614
share->db_record_offset= 1;
616
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
618
share->keys= table.indexes_size();
621
for (int indx= 0; indx < table.indexes_size(); indx++)
622
share->key_parts+= table.indexes(indx).index_part_size();
624
share->key_info= (KEY*) share->alloc_root( table.indexes_size() * sizeof(KEY) +share->key_parts*sizeof(KEY_PART_INFO));
626
KEY_PART_INFO *key_part;
628
key_part= reinterpret_cast<KEY_PART_INFO*>
629
(share->key_info+table.indexes_size());
632
ulong *rec_per_key= (ulong*) share->alloc_root(sizeof(ulong*)*share->key_parts);
634
KEY* keyinfo= share->key_info;
635
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
637
message::Table::Index indx= table.indexes(keynr);
642
if (indx.is_unique())
643
keyinfo->flags|= HA_NOSAME;
645
if (indx.has_options())
647
message::Table::Index::IndexOptions indx_options= indx.options();
648
if (indx_options.pack_key())
649
keyinfo->flags|= HA_PACK_KEY;
651
if (indx_options.var_length_key())
652
keyinfo->flags|= HA_VAR_LENGTH_PART;
654
if (indx_options.null_part_key())
655
keyinfo->flags|= HA_NULL_PART_KEY;
657
if (indx_options.binary_pack_key())
658
keyinfo->flags|= HA_BINARY_PACK_KEY;
660
if (indx_options.has_partial_segments())
661
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
663
if (indx_options.auto_generated_key())
664
keyinfo->flags|= HA_GENERATED_KEY;
666
if (indx_options.has_key_block_size())
668
keyinfo->flags|= HA_USES_BLOCK_SIZE;
669
keyinfo->block_size= indx_options.key_block_size();
673
keyinfo->block_size= 0;
679
case message::Table::Index::UNKNOWN_INDEX:
680
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
682
case message::Table::Index::BTREE:
683
keyinfo->algorithm= HA_KEY_ALG_BTREE;
685
case message::Table::Index::HASH:
686
keyinfo->algorithm= HA_KEY_ALG_HASH;
690
/* TODO: suitable warning ? */
691
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
695
keyinfo->key_length= indx.key_length();
697
keyinfo->key_parts= indx.index_part_size();
699
keyinfo->key_part= key_part;
700
keyinfo->rec_per_key= rec_per_key;
702
for (unsigned int partnr= 0;
703
partnr < keyinfo->key_parts;
704
partnr++, key_part++)
706
message::Table::Index::IndexPart part;
707
part= indx.index_part(partnr);
711
key_part->field= NULL;
712
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
713
key_part->null_bit= 0;
714
/* key_part->null_offset is only set if null_bit (see later) */
715
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
716
/* key_part->type ???? */
717
key_part->key_part_flag= 0;
718
if (part.has_in_reverse_order())
719
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
721
key_part->length= part.compare_length();
723
key_part->store_length= key_part->length;
725
/* key_part->offset is set later */
726
key_part->key_type= part.key_type();
729
if (! indx.has_comment())
731
keyinfo->comment.length= 0;
732
keyinfo->comment.str= NULL;
736
keyinfo->flags|= HA_USES_COMMENT;
737
keyinfo->comment.length= indx.comment().length();
738
keyinfo->comment.str= share->strmake_root(indx.comment().c_str(), keyinfo->comment.length);
741
keyinfo->name= share->strmake_root(indx.name().c_str(), indx.name().length());
743
addKeyName(string(keyinfo->name, indx.name().length()));
746
share->keys_for_keyread.reset();
747
set_prefix(share->keys_in_use, share->keys);
749
share->fields= table.field_size();
751
share->field= (Field**) share->alloc_root(((share->fields+1) * sizeof(Field*)));
752
share->field[share->fields]= NULL;
754
uint32_t local_null_fields= 0;
757
vector<uint32_t> field_offsets;
758
vector<uint32_t> field_pack_length;
760
field_offsets.resize(share->fields);
761
field_pack_length.resize(share->fields);
763
uint32_t interval_count= 0;
764
uint32_t interval_parts= 0;
766
uint32_t stored_columns_reclength= 0;
768
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
770
message::Table::Field pfield= table.field(fieldnr);
771
if (pfield.constraints().is_nullable())
774
enum_field_types drizzle_field_type=
775
proto_field_type_to_drizzle_type(pfield.type());
777
field_offsets[fieldnr]= stored_columns_reclength;
779
/* the below switch is very similar to
780
CreateField::create_length_to_internal_length in field.cc
781
(which should one day be replace by just this code)
783
switch(drizzle_field_type)
785
case DRIZZLE_TYPE_BLOB:
786
case DRIZZLE_TYPE_VARCHAR:
788
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
790
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
791
field_options.collation_id() : 0);
794
cs= default_charset_info;
796
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
797
field_options.length() * cs->mbmaxlen);
800
case DRIZZLE_TYPE_ENUM:
802
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
804
field_pack_length[fieldnr]=
805
get_enum_pack_length(field_options.field_value_size());
808
interval_parts+= field_options.field_value_size();
811
case DRIZZLE_TYPE_DECIMAL:
813
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
815
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
819
/* Zero is okay here as length is fixed for other types. */
820
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
823
share->reclength+= field_pack_length[fieldnr];
824
stored_columns_reclength+= field_pack_length[fieldnr];
827
/* data_offset added to stored_rec_length later */
828
share->stored_rec_length= stored_columns_reclength;
830
share->null_fields= local_null_fields;
832
ulong null_bits= local_null_fields;
833
if (! table_options.pack_record())
835
ulong data_offset= (null_bits + 7)/8;
838
share->reclength+= data_offset;
839
share->stored_rec_length+= data_offset;
841
ulong local_rec_buff_length;
843
local_rec_buff_length= ALIGN_SIZE(share->reclength + 1);
844
share->rec_buff_length= local_rec_buff_length;
846
unsigned char* record= NULL;
848
if (! (record= (unsigned char *) share->alloc_root(local_rec_buff_length)))
851
memset(record, 0, local_rec_buff_length);
855
if (! table_options.pack_record())
857
null_count++; // one bit for delete mark.
861
share->default_values= record;
865
share->intervals= (TYPELIB *) share->alloc_root(interval_count*sizeof(TYPELIB));
869
share->intervals= NULL;
872
share->fieldnames.type_names= (const char **) share->alloc_root((share->fields + 1) * sizeof(char*));
874
share->fieldnames.type_lengths= (unsigned int *) share->alloc_root((share->fields + 1) * sizeof(unsigned int));
876
share->fieldnames.type_names[share->fields]= NULL;
877
share->fieldnames.type_lengths[share->fields]= 0;
878
share->fieldnames.count= share->fields;
881
/* Now fix the TYPELIBs for the intervals (enum values)
885
uint32_t interval_nr= 0;
887
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
889
message::Table::Field pfield= table.field(fieldnr);
892
share->fieldnames.type_names[fieldnr]= share->strmake_root(pfield.name().c_str(), pfield.name().length());
894
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
897
if (pfield.type() != message::Table::Field::ENUM)
900
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
902
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
903
field_options.collation_id() : 0);
906
charset= default_charset_info;
908
TYPELIB *t= &(share->intervals[interval_nr]);
910
t->type_names= (const char**)share->alloc_root((field_options.field_value_size() + 1) * sizeof(char*));
912
t->type_lengths= (unsigned int*) share->alloc_root((field_options.field_value_size() + 1) * sizeof(unsigned int));
914
t->type_names[field_options.field_value_size()]= NULL;
915
t->type_lengths[field_options.field_value_size()]= 0;
917
t->count= field_options.field_value_size();
920
for (int n= 0; n < field_options.field_value_size(); n++)
922
t->type_names[n]= share->strmake_root(field_options.field_value(n).c_str(), field_options.field_value(n).length());
925
* Go ask the charset what the length is as for "" length=1
926
* and there's stripping spaces or some other crack going on.
929
lengthsp= charset->cset->lengthsp(charset,
931
field_options.field_value(n).length());
932
t->type_lengths[n]= lengthsp;
938
/* and read the fields */
941
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
944
use_hash= ! hash_init(&share->name_hash,
949
(hash_get_key) get_field_name,
953
unsigned char* null_pos= record;;
954
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
956
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
958
message::Table::Field pfield= table.field(fieldnr);
960
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
962
switch (pfield.format())
964
case message::Table::Field::DefaultFormat:
965
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
967
case message::Table::Field::FixedFormat:
968
column_format= COLUMN_FORMAT_TYPE_FIXED;
970
case message::Table::Field::DynamicFormat:
971
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
977
Field::utype unireg_type= Field::NONE;
979
if (pfield.has_numeric_options() &&
980
pfield.numeric_options().is_autoincrement())
982
unireg_type= Field::NEXT_NUMBER;
985
if (pfield.has_options() &&
986
pfield.options().has_default_value() &&
987
pfield.options().default_value().compare("NOW()") == 0)
989
if (pfield.options().has_update_value() &&
990
pfield.options().update_value().compare("NOW()") == 0)
992
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
994
else if (! pfield.options().has_update_value())
996
unireg_type= Field::TIMESTAMP_DN_FIELD;
999
assert(1); // Invalid update value.
1001
else if (pfield.has_options() &&
1002
pfield.options().has_update_value() &&
1003
pfield.options().update_value().compare("NOW()") == 0)
1005
unireg_type= Field::TIMESTAMP_UN_FIELD;
1009
if (!pfield.has_comment())
1011
comment.str= (char*)"";
1016
size_t len= pfield.comment().length();
1017
const char* str= pfield.comment().c_str();
1019
comment.str= share->strmake_root(str, len);
1020
comment.length= len;
1023
enum_field_types field_type;
1025
field_type= proto_field_type_to_drizzle_type(pfield.type());
1027
const CHARSET_INFO *charset= &my_charset_bin;
1029
if (field_type == DRIZZLE_TYPE_BLOB ||
1030
field_type == DRIZZLE_TYPE_VARCHAR)
1032
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1034
charset= get_charset(field_options.has_collation_id() ?
1035
field_options.collation_id() : 0);
1038
charset= default_charset_info;
1041
if (field_type == DRIZZLE_TYPE_ENUM)
1043
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
1045
charset= get_charset(field_options.has_collation_id()?
1046
field_options.collation_id() : 0);
1049
charset= default_charset_info;
1052
uint8_t decimals= 0;
1053
if (field_type == DRIZZLE_TYPE_DECIMAL
1054
|| field_type == DRIZZLE_TYPE_DOUBLE)
1056
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1058
if (! pfield.has_numeric_options() || ! fo.has_scale())
1061
We don't write the default to table proto so
1062
if no decimals specified for DOUBLE, we use the default.
1064
decimals= NOT_FIXED_DEC;
1068
if (fo.scale() > DECIMAL_MAX_SCALE)
1074
decimals= static_cast<uint8_t>(fo.scale());
1078
Item *default_value= NULL;
1080
if (pfield.options().has_default_value() ||
1081
pfield.options().has_default_null() ||
1082
pfield.options().has_default_bin_value())
1084
default_value= default_value_item(field_type,
1086
pfield.options().default_null(),
1087
&pfield.options().default_value(),
1088
&pfield.options().default_bin_value());
1092
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
1093
memset(&temp_table, 0, sizeof(temp_table));
1094
temp_table.s= share;
1095
temp_table.in_use= &session;
1096
temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
1097
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
1099
uint32_t field_length= 0; //Assignment is for compiler complaint.
1103
case DRIZZLE_TYPE_BLOB:
1104
case DRIZZLE_TYPE_VARCHAR:
1106
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1108
charset= get_charset(field_options.has_collation_id() ?
1109
field_options.collation_id() : 0);
1112
charset= default_charset_info;
1114
field_length= field_options.length() * charset->mbmaxlen;
1117
case DRIZZLE_TYPE_DOUBLE:
1119
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1120
if (!fo.has_precision() && !fo.has_scale())
1122
field_length= DBL_DIG+7;
1126
field_length= fo.precision();
1128
if (field_length < decimals &&
1129
decimals != NOT_FIXED_DEC)
1131
my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
1138
case DRIZZLE_TYPE_DECIMAL:
1140
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1142
field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
1146
case DRIZZLE_TYPE_TIMESTAMP:
1147
case DRIZZLE_TYPE_DATETIME:
1148
field_length= DateTime::MAX_STRING_LENGTH;
1150
case DRIZZLE_TYPE_DATE:
1151
field_length= Date::MAX_STRING_LENGTH;
1153
case DRIZZLE_TYPE_ENUM:
1157
message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
1159
for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
1161
if (fo.field_value(valnr).length() > field_length)
1163
field_length= charset->cset->numchars(charset,
1164
fo.field_value(valnr).c_str(),
1165
fo.field_value(valnr).c_str()
1166
+ fo.field_value(valnr).length())
1167
* charset->mbmaxlen;
1172
case DRIZZLE_TYPE_LONG:
1174
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
1175
field_length= MAX_INT_WIDTH+sign_len;
1178
case DRIZZLE_TYPE_LONGLONG:
1179
field_length= MAX_BIGINT_WIDTH;
1181
case DRIZZLE_TYPE_NULL:
1182
abort(); // Programming error
1185
Field* f= share->make_field(record + field_offsets[fieldnr] + data_offset,
1187
pfield.constraints().is_nullable(),
1193
(Field::utype) MTYP_TYPENR(unireg_type),
1194
((field_type == DRIZZLE_TYPE_ENUM) ?
1195
share->intervals + (interval_nr++)
1197
share->fieldnames.type_names[fieldnr]);
1199
share->field[fieldnr]= f;
1201
f->init(&temp_table); /* blob default values need table obj */
1203
if (! (f->flags & NOT_NULL_FLAG))
1205
*f->null_ptr|= f->null_bit;
1206
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
1213
enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
1214
session.count_cuted_fields= CHECK_FIELD_WARN;
1215
int res= default_value->save_in_field(f, 1);
1216
session.count_cuted_fields= old_count_cuted_fields;
1217
if (res != 0 && res != 3) /* @TODO Huh? */
1219
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
1225
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
1226
(f->flags & NOT_NULL_FLAG))
1229
f->store((int64_t) 1, true);
1236
/* hack to undo f->init() */
1238
f->orig_table= NULL;
1240
f->field_index= fieldnr;
1241
f->comment= comment;
1242
if (! default_value &&
1243
! (f->unireg_check==Field::NEXT_NUMBER) &&
1244
(f->flags & NOT_NULL_FLAG) &&
1245
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
1247
f->flags|= NO_DEFAULT_VALUE_FLAG;
1250
if (f->unireg_check == Field::NEXT_NUMBER)
1251
share->found_next_number_field= &(share->field[fieldnr]);
1253
if (share->timestamp_field == f)
1254
share->timestamp_field_offset= fieldnr;
1256
if (use_hash) /* supposedly this never fails... but comments lie */
1257
(void) my_hash_insert(&share->name_hash,
1258
(unsigned char*)&(share->field[fieldnr]));
1262
keyinfo= share->key_info;
1263
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
1265
key_part= keyinfo->key_part;
1267
for (unsigned int partnr= 0;
1268
partnr < keyinfo->key_parts;
1269
partnr++, key_part++)
1272
* Fix up key_part->offset by adding data_offset.
1273
* We really should compute offset as well.
1274
* But at least this way we are a little better.
1276
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1281
We need to set the unused bits to 1. If the number of bits is a multiple
1282
of 8 there are no unused bits.
1286
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1288
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1290
share->last_null_bit_pos= null_bit_pos;
1293
if (share->key_parts)
1295
uint32_t local_primary_key= 0;
1296
doesKeyNameExist("PRIMARY", local_primary_key);
1298
keyinfo= share->key_info;
1299
key_part= keyinfo->key_part;
1301
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
1303
uint32_t usable_parts= 0;
1305
if (local_primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1308
If the UNIQUE key doesn't have NULL columns and is not a part key
1309
declare this as a primary key.
1311
local_primary_key=key;
1312
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1314
uint32_t fieldnr= key_part[i].fieldnr;
1316
share->field[fieldnr-1]->null_ptr ||
1317
share->field[fieldnr-1]->key_length() != key_part[i].length)
1319
local_primary_key= MAX_KEY; // Can't be used
1325
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1328
if (! key_part->fieldnr)
1332
local_field= key_part->field= share->field[key_part->fieldnr-1];
1333
key_part->type= local_field->key_type();
1334
if (local_field->null_ptr)
1336
key_part->null_offset=(uint32_t) ((unsigned char*) local_field->null_ptr - share->default_values);
1337
key_part->null_bit= local_field->null_bit;
1338
key_part->store_length+=HA_KEY_NULL_LENGTH;
1339
keyinfo->flags|=HA_NULL_PART_KEY;
1340
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1341
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1343
if (local_field->type() == DRIZZLE_TYPE_BLOB ||
1344
local_field->real_type() == DRIZZLE_TYPE_VARCHAR)
1346
if (local_field->type() == DRIZZLE_TYPE_BLOB)
1347
key_part->key_part_flag|= HA_BLOB_PART;
1349
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1350
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1351
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1352
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1354
if (i == 0 && key != local_primary_key)
1355
local_field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1356
(keyinfo->key_parts == 1)) ?
1357
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1359
local_field->key_start.set(key);
1360
if (local_field->key_length() == key_part->length &&
1361
!(local_field->flags & BLOB_FLAG))
1363
enum ha_key_alg algo= share->key_info[key].algorithm;
1364
if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1366
share->keys_for_keyread.set(key);
1367
local_field->part_of_key.set(key);
1368
local_field->part_of_key_not_clustered.set(key);
1370
if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1371
local_field->part_of_sortkey.set(key);
1373
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1375
usable_parts++; // For FILESORT
1376
local_field->flags|= PART_KEY_FLAG;
1377
if (key == local_primary_key)
1379
local_field->flags|= PRI_KEY_FLAG;
1381
If this field is part of the primary key and all keys contains
1382
the primary key, then we can use any key to find this column
1384
if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1386
local_field->part_of_key= share->keys_in_use;
1387
if (local_field->part_of_sortkey.test(key))
1388
local_field->part_of_sortkey= share->keys_in_use;
1391
if (local_field->key_length() != key_part->length)
1393
key_part->key_part_flag|= HA_PART_KEY_SEG;
1396
keyinfo->usable_key_parts= usable_parts; // Filesort
1398
set_if_bigger(share->max_key_length,keyinfo->key_length+
1399
keyinfo->key_parts);
1400
share->total_key_length+= keyinfo->key_length;
1402
if (keyinfo->flags & HA_NOSAME)
1404
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1407
if (local_primary_key < MAX_KEY &&
1408
(share->keys_in_use.test(local_primary_key)))
1410
share->primary_key= local_primary_key;
1412
If we are using an integer as the primary key then allow the user to
1413
refer to it as '_rowid'
1415
if (share->key_info[local_primary_key].key_parts == 1)
1417
Field *local_field= share->key_info[local_primary_key].key_part[0].field;
1418
if (local_field && local_field->result_type() == INT_RESULT)
1420
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1421
share->rowid_field_offset= (share->key_info[local_primary_key].key_part[0].
1428
share->primary_key = MAX_KEY; // we do not have a primary key
1433
share->primary_key= MAX_KEY;
1436
if (share->found_next_number_field)
1438
Field *reg_field= *share->found_next_number_field;
1439
if ((int) (share->next_number_index= (uint32_t)
1440
find_ref_key(share->key_info, share->keys,
1441
share->default_values, reg_field,
1442
&share->next_number_key_offset,
1443
&share->next_number_keypart)) < 0)
1445
/* Wrong field definition */
1452
reg_field->flags |= AUTO_INCREMENT_FLAG;
1456
if (share->blob_fields)
1461
/* Store offsets to blob fields to find them fast */
1462
if (!(share->blob_field= save=
1463
(uint*) share->alloc_root((uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1467
for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1469
if ((*ptr)->flags & BLOB_FLAG)
1474
share->db_low_byte_first= true; // @todo Question this.
1475
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1477
my_bitmap_map *bitmaps;
1479
if (!(bitmaps= (my_bitmap_map*) share->alloc_root(share->column_bitmap_size)))
1483
share->all_set.init(bitmaps, share->fields);
1484
share->all_set.setAll();
1492
int TableShare::parse_table_proto(Session& session, message::Table &table)
1494
int local_error= inner_parse_table_proto(session, table);
1496
if (not local_error)
1502
hash_free(&name_hash);
1503
open_table_error(local_error, open_errno, 0);
1510
Read table definition from a binary / text based .frm cursor
1514
session Thread Cursor
1515
share Fill this with table definition
1518
This function is called when the table definition is not cached in
1520
The data is returned in 'share', which is alloced by
1521
alloc_table_share().. The code assumes that share is initialized.
1525
1 Error (see open_table_error)
1526
2 Error (see open_table_error)
1527
3 Wrong data in .frm cursor
1528
4 Error (see open_table_error)
1529
5 Error (see open_table_error: charset unavailable)
1530
6 Unknown .frm version
1533
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1541
message::Table table;
1543
local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1545
if (local_error != EEXIST)
1547
if (local_error > 0)
1554
if (not table.IsInitialized())
1562
local_error= parse_table_proto(session, table);
1564
setTableCategory(TABLE_CATEGORY_USER);
1567
if (local_error && !error_given)
1570
open_table_error(error, (open_errno= errno), 0);
1578
Open a table based on a TableShare
1581
open_table_from_share()
1582
session Thread Cursor
1583
share Table definition
1584
alias Alias for table
1585
db_stat open flags (for example HA_OPEN_KEYFILE|
1586
HA_OPEN_RNDFILE..) can be 0 (example in
1588
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1589
outparam result table
1593
1 Error (see open_table_error)
1594
2 Error (see open_table_error)
1595
3 Wrong data in .frm cursor
1596
4 Error (see open_table_error)
1597
5 Error (see open_table_error: charset unavailable)
1598
7 Table definition has changed in engine
1601
int TableShare::open_table_from_share(Session *session, const char *alias,
1602
uint32_t db_stat, uint32_t ha_open_flags,
1606
uint32_t records, bitmap_size;
1607
bool error_reported= false;
1608
unsigned char *record, *bitmaps;
1611
/* Parsing of partitioning information from .frm needs session->lex set up. */
1612
assert(session->lex->is_lex_started);
1615
outparam.resetTable(session, this, db_stat);
1618
if (not (outparam.alias= strdup(alias)))
1621
/* Allocate Cursor */
1622
if (not (outparam.cursor= db_type()->getCursor(*this, &outparam.mem_root)))
1627
if ((db_stat & HA_OPEN_KEYFILE))
1632
if (!(record= (unsigned char*) outparam.mem_root.alloc_root(rec_buff_length * records)))
1637
/* We are probably in hard repair, and the buffers should not be used */
1638
outparam.record[0]= outparam.record[1]= default_values;
1642
outparam.record[0]= record;
1644
outparam.record[1]= record+ rec_buff_length;
1646
outparam.record[1]= outparam.record[0]; // Safety
1651
We need this because when we read var-length rows, we are not updating
1652
bytes after end of varchar
1656
memcpy(outparam.record[0], default_values, rec_buff_length);
1657
memcpy(outparam.record[1], default_values, null_bytes);
1659
memcpy(outparam.record[1], default_values, rec_buff_length);
1664
memcpy(outparam.record[1], default_values, null_bytes);
1667
if (!(field_ptr = (Field **) outparam.mem_root.alloc_root( (uint32_t) ((fields+1)* sizeof(Field*)))))
1672
outparam.field= field_ptr;
1674
record= (unsigned char*) outparam.record[0]-1; /* Fieldstart = 1 */
1676
outparam.null_flags= (unsigned char*) record+1;
1678
/* Setup copy of fields from share, but use the right alias and record */
1679
for (uint32_t i= 0 ; i < fields; i++, field_ptr++)
1681
if (!((*field_ptr)= field[i]->clone(&outparam.mem_root, &outparam)))
1684
(*field_ptr)= 0; // End marker
1686
if (found_next_number_field)
1687
outparam.found_next_number_field=
1688
outparam.field[(uint32_t) (found_next_number_field - field)];
1689
if (timestamp_field)
1690
outparam.timestamp_field= (Field_timestamp*) outparam.field[timestamp_field_offset];
1693
/* Fix key->name and key_part->field */
1696
KEY *local_key_info, *key_info_end;
1697
KEY_PART_INFO *key_part;
1699
n_length= keys*sizeof(KEY) + key_parts*sizeof(KEY_PART_INFO);
1700
if (!(local_key_info= (KEY*) outparam.mem_root.alloc_root(n_length)))
1702
outparam.key_info= local_key_info;
1703
key_part= (reinterpret_cast<KEY_PART_INFO*> (local_key_info+keys));
1705
memcpy(local_key_info, key_info, sizeof(*local_key_info)*keys);
1706
memcpy(key_part, key_info[0].key_part, (sizeof(*key_part) *
1709
for (key_info_end= local_key_info + keys ;
1710
local_key_info < key_info_end ;
1713
KEY_PART_INFO *key_part_end;
1715
local_key_info->table= &outparam;
1716
local_key_info->key_part= key_part;
1718
for (key_part_end= key_part+ local_key_info->key_parts ;
1719
key_part < key_part_end ;
1722
Field *local_field= key_part->field= outparam.field[key_part->fieldnr-1];
1724
if (local_field->key_length() != key_part->length &&
1725
!(local_field->flags & BLOB_FLAG))
1728
We are using only a prefix of the column as a key:
1729
Create a new field for the key part that matches the index
1731
local_field= key_part->field= local_field->new_field(&outparam.mem_root, &outparam, 0);
1732
local_field->field_length= key_part->length;
1738
/* Allocate bitmaps */
1740
bitmap_size= column_bitmap_size;
1741
if (!(bitmaps= (unsigned char*) outparam.mem_root.alloc_root(bitmap_size*3)))
1745
outparam.def_read_set.init((my_bitmap_map*) bitmaps, fields);
1746
outparam.def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), fields);
1747
outparam.tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), fields);
1748
outparam.default_column_bitmaps();
1750
/* The table struct is now initialized; Open the table */
1755
if ((ha_err= (outparam.cursor->
1756
ha_open(&outparam, getNormalizedPath(),
1757
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1758
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1759
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1760
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1761
HA_OPEN_ABORT_IF_LOCKED :
1762
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1766
case HA_ERR_NO_SUCH_TABLE:
1768
The table did not exists in storage engine, use same error message
1769
as if the .frm cursor didn't exist
1776
Too many files opened, use same error message as if the .frm
1783
outparam.print_error(ha_err, MYF(0));
1784
error_reported= true;
1785
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1793
#if defined(HAVE_purify)
1794
memset(bitmaps, 0, bitmap_size*3);
1800
if (!error_reported)
1801
open_table_error(local_error, errno, 0);
1803
delete outparam.cursor;
1804
outparam.cursor= 0; // For easier error checking
1805
outparam.db_stat= 0;
1806
outparam.mem_root.free_root(MYF(0)); // Safe to call on zeroed root
1807
free((char*) outparam.alias);
1808
return (local_error);
1811
/* error message when opening a form cursor */
1812
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1815
char buff[FN_REFLEN];
1816
myf errortype= ME_ERROR+ME_WAITTANG;
1818
switch (pass_error) {
1821
if (db_errno == ENOENT)
1823
my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1827
snprintf(buff, sizeof(buff), "%s",normalized_path.str);
1828
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1829
errortype, buff, db_errno);
1835
const char *datext= "";
1837
if (db_type() != NULL)
1839
if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
1841
if (!(datext= *db_type()->bas_ext()))
1845
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1846
ER_FILE_USED : ER_CANT_OPEN_FILE;
1847
snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
1848
my_error(err_no,errortype, buff, db_errno);
1854
const char *csname= get_charset_name((uint32_t) pass_errarg);
1856
if (!csname || csname[0] =='?')
1858
snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
1861
my_printf_error(ER_UNKNOWN_COLLATION,
1862
_("Unknown collation '%s' in table '%-.64s' definition"),
1863
MYF(0), csname, table_name.str);
1867
snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1868
my_printf_error(ER_NOT_FORM_FILE,
1869
_("Table '%-.64s' was created with a different version "
1870
"of Drizzle and cannot be read"),
1875
default: /* Better wrong error than none */
1877
snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1878
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1882
} /* open_table_error */
421
1885
} /* namespace drizzled */