73
75
/*************************************************************************/
75
/* Get column name from column hash */
77
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
79
*length= (uint32_t) strlen((*buff)->field_name);
80
return (unsigned char*) (*buff)->field_name;
83
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
87
if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
88
(my_strcasecmp(system_charset_info,
89
INFORMATION_SCHEMA_NAME.c_str(),
92
return TABLE_CATEGORY_INFORMATION;
95
return TABLE_CATEGORY_USER;
100
Allocate a setup TableShare structure
104
TableList Take database and table name from there
105
key Table cache key (db \0 table_name \0...)
106
key_length Length of key
109
0 Error (out of memory)
113
TableShare *alloc_table_share(TableList *table_list, char *key,
116
memory::Root mem_root;
118
char *key_buff, *path_buff;
119
char path[FN_REFLEN];
120
uint32_t path_length;
122
path_length= build_table_filename(path, sizeof(path) - 1,
124
table_list->table_name, false);
125
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
126
if (multi_alloc_root(&mem_root,
127
&share, sizeof(*share),
128
&key_buff, key_length,
129
&path_buff, path_length + 1,
132
memset(share, 0, sizeof(*share));
134
share->set_table_cache_key(key_buff, key, key_length);
136
share->path.str= path_buff;
137
share->path.length= path_length;
138
strcpy(share->path.str, path);
139
share->normalized_path.str= share->path.str;
140
share->normalized_path.length= path_length;
142
share->version= refresh_version;
144
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
145
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
146
pthread_cond_init(&share->cond, NULL);
152
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
154
enum_field_types field_type;
156
switch(proto_field_type)
158
case message::Table::Field::INTEGER:
159
field_type= DRIZZLE_TYPE_LONG;
161
case message::Table::Field::DOUBLE:
162
field_type= DRIZZLE_TYPE_DOUBLE;
164
case message::Table::Field::TIMESTAMP:
165
field_type= DRIZZLE_TYPE_TIMESTAMP;
167
case message::Table::Field::BIGINT:
168
field_type= DRIZZLE_TYPE_LONGLONG;
170
case message::Table::Field::DATETIME:
171
field_type= DRIZZLE_TYPE_DATETIME;
173
case message::Table::Field::DATE:
174
field_type= DRIZZLE_TYPE_DATE;
176
case message::Table::Field::VARCHAR:
177
field_type= DRIZZLE_TYPE_VARCHAR;
179
case message::Table::Field::DECIMAL:
180
field_type= DRIZZLE_TYPE_DECIMAL;
182
case message::Table::Field::ENUM:
183
field_type= DRIZZLE_TYPE_ENUM;
185
case message::Table::Field::BLOB:
186
field_type= DRIZZLE_TYPE_BLOB;
189
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
196
static Item *default_value_item(enum_field_types field_type,
197
const CHARSET_INFO *charset,
198
bool default_null, const string *default_value,
199
const string *default_bin_value)
201
Item *default_item= NULL;
206
return new Item_null();
211
case DRIZZLE_TYPE_LONG:
212
case DRIZZLE_TYPE_LONGLONG:
213
default_item= new Item_int(default_value->c_str(),
214
(int64_t) internal::my_strtoll10(default_value->c_str(),
217
default_value->length());
219
case DRIZZLE_TYPE_DOUBLE:
220
default_item= new Item_float(default_value->c_str(),
221
default_value->length());
223
case DRIZZLE_TYPE_NULL:
225
case DRIZZLE_TYPE_TIMESTAMP:
226
case DRIZZLE_TYPE_DATETIME:
227
case DRIZZLE_TYPE_DATE:
228
if (default_value->compare("NOW()") == 0)
230
case DRIZZLE_TYPE_ENUM:
231
default_item= new Item_string(default_value->c_str(),
232
default_value->length(),
233
system_charset_info);
235
case DRIZZLE_TYPE_VARCHAR:
236
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
237
if (charset==&my_charset_bin)
239
default_item= new Item_string(default_bin_value->c_str(),
240
default_bin_value->length(),
245
default_item= new Item_string(default_value->c_str(),
246
default_value->length(),
247
system_charset_info);
250
case DRIZZLE_TYPE_DECIMAL:
251
default_item= new Item_decimal(default_value->c_str(),
252
default_value->length(),
253
system_charset_info);
260
int parse_table_proto(Session& session,
261
message::Table &table,
266
if (! table.IsInitialized())
268
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
269
return ER_CORRUPT_TABLE_DEFINITION;
272
share->setTableProto(new(nothrow) message::Table(table));
274
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
275
assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
277
message::Table::TableOptions table_options;
279
if (table.has_options())
280
table_options= table.options();
282
uint32_t db_create_options= 0;
284
if (table_options.has_pack_keys())
286
if (table_options.pack_keys())
287
db_create_options|= HA_OPTION_PACK_KEYS;
289
db_create_options|= HA_OPTION_NO_PACK_KEYS;
292
if (table_options.pack_record())
293
db_create_options|= HA_OPTION_PACK_RECORD;
295
/* db_create_options was stored as 2 bytes in FRM
296
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
298
share->db_create_options= (db_create_options & 0x0000FFFF);
299
share->db_options_in_use= share->db_create_options;
301
share->row_type= table_options.has_row_type() ?
302
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
304
share->block_size= table_options.has_block_size() ?
305
table_options.block_size() : 0;
307
share->table_charset= get_charset(table_options.has_collation_id()?
308
table_options.collation_id() : 0);
310
if (!share->table_charset)
312
/* unknown charset in head[38] or pre-3.23 frm */
313
if (use_mb(default_charset_info))
315
/* Warn that we may be changing the size of character columns */
316
errmsg_printf(ERRMSG_LVL_WARN,
317
_("'%s' had no or invalid character set, "
318
"and default character set is multi-byte, "
319
"so character column sizes may have changed"),
322
share->table_charset= default_charset_info;
325
share->db_record_offset= 1;
327
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
329
share->keys= table.indexes_size();
332
for (int indx= 0; indx < table.indexes_size(); indx++)
333
share->key_parts+= table.indexes(indx).index_part_size();
335
share->key_info= (KEY*) alloc_root(&share->mem_root,
336
table.indexes_size() * sizeof(KEY)
337
+share->key_parts*sizeof(KEY_PART_INFO));
339
KEY_PART_INFO *key_part;
341
key_part= reinterpret_cast<KEY_PART_INFO*>
342
(share->key_info+table.indexes_size());
345
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
346
sizeof(ulong*)*share->key_parts);
348
share->keynames.count= table.indexes_size();
349
share->keynames.name= NULL;
350
share->keynames.type_names= (const char**)
351
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
353
share->keynames.type_lengths= (unsigned int*)
354
alloc_root(&share->mem_root,
355
sizeof(unsigned int) * (table.indexes_size()+1));
357
share->keynames.type_names[share->keynames.count]= NULL;
358
share->keynames.type_lengths[share->keynames.count]= 0;
360
KEY* keyinfo= share->key_info;
361
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
363
message::Table::Index indx= table.indexes(keynr);
368
if (indx.is_unique())
369
keyinfo->flags|= HA_NOSAME;
371
if (indx.has_options())
373
message::Table::Index::IndexOptions indx_options= indx.options();
374
if (indx_options.pack_key())
375
keyinfo->flags|= HA_PACK_KEY;
377
if (indx_options.var_length_key())
378
keyinfo->flags|= HA_VAR_LENGTH_PART;
380
if (indx_options.null_part_key())
381
keyinfo->flags|= HA_NULL_PART_KEY;
383
if (indx_options.binary_pack_key())
384
keyinfo->flags|= HA_BINARY_PACK_KEY;
386
if (indx_options.has_partial_segments())
387
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
389
if (indx_options.auto_generated_key())
390
keyinfo->flags|= HA_GENERATED_KEY;
392
if (indx_options.has_key_block_size())
394
keyinfo->flags|= HA_USES_BLOCK_SIZE;
395
keyinfo->block_size= indx_options.key_block_size();
399
keyinfo->block_size= 0;
405
case message::Table::Index::UNKNOWN_INDEX:
406
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
408
case message::Table::Index::BTREE:
409
keyinfo->algorithm= HA_KEY_ALG_BTREE;
411
case message::Table::Index::HASH:
412
keyinfo->algorithm= HA_KEY_ALG_HASH;
416
/* TODO: suitable warning ? */
417
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
421
keyinfo->key_length= indx.key_length();
423
keyinfo->key_parts= indx.index_part_size();
425
keyinfo->key_part= key_part;
426
keyinfo->rec_per_key= rec_per_key;
428
for (unsigned int partnr= 0;
429
partnr < keyinfo->key_parts;
430
partnr++, key_part++)
432
message::Table::Index::IndexPart part;
433
part= indx.index_part(partnr);
437
key_part->field= NULL;
438
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
439
key_part->null_bit= 0;
440
/* key_part->null_offset is only set if null_bit (see later) */
441
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
442
/* key_part->type ???? */
443
key_part->key_part_flag= 0;
444
if (part.has_in_reverse_order())
445
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
447
key_part->length= part.compare_length();
449
key_part->store_length= key_part->length;
451
/* key_part->offset is set later */
452
key_part->key_type= part.key_type();
455
if (! indx.has_comment())
457
keyinfo->comment.length= 0;
458
keyinfo->comment.str= NULL;
462
keyinfo->flags|= HA_USES_COMMENT;
463
keyinfo->comment.length= indx.comment().length();
464
keyinfo->comment.str= strmake_root(&share->mem_root,
465
indx.comment().c_str(),
466
keyinfo->comment.length);
469
keyinfo->name= strmake_root(&share->mem_root,
471
indx.name().length());
473
share->keynames.type_names[keynr]= keyinfo->name;
474
share->keynames.type_lengths[keynr]= indx.name().length();
477
share->keys_for_keyread.reset();
478
set_prefix(share->keys_in_use, share->keys);
480
share->fields= table.field_size();
482
share->field= (Field**) alloc_root(&share->mem_root,
483
((share->fields+1) * sizeof(Field*)));
484
share->field[share->fields]= NULL;
486
uint32_t null_fields= 0;
489
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
490
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
492
assert(field_offsets && field_pack_length); // TODO: fixme
494
uint32_t interval_count= 0;
495
uint32_t interval_parts= 0;
497
uint32_t stored_columns_reclength= 0;
499
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
501
message::Table::Field pfield= table.field(fieldnr);
502
if (pfield.constraints().is_nullable())
505
enum_field_types drizzle_field_type=
506
proto_field_type_to_drizzle_type(pfield.type());
508
field_offsets[fieldnr]= stored_columns_reclength;
510
/* the below switch is very similar to
511
CreateField::create_length_to_internal_length in field.cc
512
(which should one day be replace by just this code)
514
switch(drizzle_field_type)
516
case DRIZZLE_TYPE_BLOB:
517
case DRIZZLE_TYPE_VARCHAR:
519
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
521
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
522
field_options.collation_id() : 0);
525
cs= default_charset_info;
527
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
528
field_options.length() * cs->mbmaxlen);
531
case DRIZZLE_TYPE_ENUM:
533
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
535
field_pack_length[fieldnr]=
536
get_enum_pack_length(field_options.field_value_size());
539
interval_parts+= field_options.field_value_size();
542
case DRIZZLE_TYPE_DECIMAL:
544
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
546
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
550
/* Zero is okay here as length is fixed for other types. */
551
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
554
share->reclength+= field_pack_length[fieldnr];
555
stored_columns_reclength+= field_pack_length[fieldnr];
558
/* data_offset added to stored_rec_length later */
559
share->stored_rec_length= stored_columns_reclength;
561
share->null_fields= null_fields;
563
ulong null_bits= null_fields;
564
if (! table_options.pack_record())
566
ulong data_offset= (null_bits + 7)/8;
569
share->reclength+= data_offset;
570
share->stored_rec_length+= data_offset;
572
ulong rec_buff_length;
574
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
575
share->rec_buff_length= rec_buff_length;
577
unsigned char* record= NULL;
579
if (! (record= (unsigned char *) alloc_root(&share->mem_root,
583
memset(record, 0, rec_buff_length);
587
if (! table_options.pack_record())
589
null_count++; // one bit for delete mark.
593
share->default_values= record;
597
share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
598
interval_count*sizeof(TYPELIB));
601
share->intervals= NULL;
603
share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
604
(share->fields + 1) * sizeof(char*));
606
share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
607
(share->fields + 1) * sizeof(unsigned int));
609
share->fieldnames.type_names[share->fields]= NULL;
610
share->fieldnames.type_lengths[share->fields]= 0;
611
share->fieldnames.count= share->fields;
614
/* Now fix the TYPELIBs for the intervals (enum values)
618
uint32_t interval_nr= 0;
620
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
622
message::Table::Field pfield= table.field(fieldnr);
625
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
626
pfield.name().c_str(),
627
pfield.name().length());
629
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
632
if (pfield.type() != message::Table::Field::ENUM)
635
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
637
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
638
field_options.collation_id() : 0);
641
charset= default_charset_info;
643
TYPELIB *t= &(share->intervals[interval_nr]);
645
t->type_names= (const char**)alloc_root(&share->mem_root,
646
(field_options.field_value_size() + 1) * sizeof(char*));
648
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
649
(field_options.field_value_size() + 1) * sizeof(unsigned int));
651
t->type_names[field_options.field_value_size()]= NULL;
652
t->type_lengths[field_options.field_value_size()]= 0;
654
t->count= field_options.field_value_size();
657
for (int n= 0; n < field_options.field_value_size(); n++)
659
t->type_names[n]= strmake_root(&share->mem_root,
660
field_options.field_value(n).c_str(),
661
field_options.field_value(n).length());
664
* Go ask the charset what the length is as for "" length=1
665
* and there's stripping spaces or some other crack going on.
668
lengthsp= charset->cset->lengthsp(charset,
670
field_options.field_value(n).length());
671
t->type_lengths[n]= lengthsp;
677
/* and read the fields */
680
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
683
use_hash= ! hash_init(&share->name_hash,
688
(hash_get_key) get_field_name,
692
unsigned char* null_pos= record;;
693
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
695
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
697
message::Table::Field pfield= table.field(fieldnr);
699
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
701
switch (pfield.format())
703
case message::Table::Field::DefaultFormat:
704
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
706
case message::Table::Field::FixedFormat:
707
column_format= COLUMN_FORMAT_TYPE_FIXED;
709
case message::Table::Field::DynamicFormat:
710
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
716
Field::utype unireg_type= Field::NONE;
718
if (pfield.has_numeric_options() &&
719
pfield.numeric_options().is_autoincrement())
721
unireg_type= Field::NEXT_NUMBER;
724
if (pfield.has_options() &&
725
pfield.options().has_default_value() &&
726
pfield.options().default_value().compare("NOW()") == 0)
728
if (pfield.options().has_update_value() &&
729
pfield.options().update_value().compare("NOW()") == 0)
731
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
733
else if (! pfield.options().has_update_value())
735
unireg_type= Field::TIMESTAMP_DN_FIELD;
738
assert(1); // Invalid update value.
740
else if (pfield.has_options() &&
741
pfield.options().has_update_value() &&
742
pfield.options().update_value().compare("NOW()") == 0)
744
unireg_type= Field::TIMESTAMP_UN_FIELD;
748
if (!pfield.has_comment())
750
comment.str= (char*)"";
755
size_t len= pfield.comment().length();
756
const char* str= pfield.comment().c_str();
758
comment.str= strmake_root(&share->mem_root, str, len);
762
enum_field_types field_type;
764
field_type= proto_field_type_to_drizzle_type(pfield.type());
766
const CHARSET_INFO *charset= &my_charset_bin;
768
if (field_type == DRIZZLE_TYPE_BLOB ||
769
field_type == DRIZZLE_TYPE_VARCHAR)
771
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
773
charset= get_charset(field_options.has_collation_id() ?
774
field_options.collation_id() : 0);
777
charset= default_charset_info;
780
if (field_type == DRIZZLE_TYPE_ENUM)
782
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
784
charset= get_charset(field_options.has_collation_id()?
785
field_options.collation_id() : 0);
788
charset= default_charset_info;
792
if (field_type == DRIZZLE_TYPE_DECIMAL
793
|| field_type == DRIZZLE_TYPE_DOUBLE)
795
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
797
if (! pfield.has_numeric_options() || ! fo.has_scale())
800
We don't write the default to table proto so
801
if no decimals specified for DOUBLE, we use the default.
803
decimals= NOT_FIXED_DEC;
807
if (fo.scale() > DECIMAL_MAX_SCALE)
812
decimals= static_cast<uint8_t>(fo.scale());
816
Item *default_value= NULL;
818
if (pfield.options().has_default_value() ||
819
pfield.options().has_default_null() ||
820
pfield.options().has_default_bin_value())
822
default_value= default_value_item(field_type,
824
pfield.options().default_null(),
825
&pfield.options().default_value(),
826
&pfield.options().default_bin_value());
830
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
831
memset(&temp_table, 0, sizeof(temp_table));
833
temp_table.in_use= &session;
834
temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
835
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
837
uint32_t field_length= 0; //Assignment is for compiler complaint.
841
case DRIZZLE_TYPE_BLOB:
842
case DRIZZLE_TYPE_VARCHAR:
844
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
846
charset= get_charset(field_options.has_collation_id() ?
847
field_options.collation_id() : 0);
850
charset= default_charset_info;
852
field_length= field_options.length() * charset->mbmaxlen;
855
case DRIZZLE_TYPE_DOUBLE:
857
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
858
if (!fo.has_precision() && !fo.has_scale())
860
field_length= DBL_DIG+7;
864
field_length= fo.precision();
866
if (field_length < decimals &&
867
decimals != NOT_FIXED_DEC)
869
my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
875
case DRIZZLE_TYPE_DECIMAL:
877
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
879
field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
883
case DRIZZLE_TYPE_TIMESTAMP:
884
case DRIZZLE_TYPE_DATETIME:
885
field_length= DateTime::MAX_STRING_LENGTH;
887
case DRIZZLE_TYPE_DATE:
888
field_length= Date::MAX_STRING_LENGTH;
890
case DRIZZLE_TYPE_ENUM:
894
message::Table::Field::SetFieldOptions fo= pfield.set_options();
896
for(int valnr= 0; valnr < fo.field_value_size(); valnr++)
898
if (fo.field_value(valnr).length() > field_length)
899
field_length= charset->cset->numchars(charset,
900
fo.field_value(valnr).c_str(),
901
fo.field_value(valnr).c_str()
902
+ fo.field_value(valnr).length())
907
case DRIZZLE_TYPE_LONG:
909
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
910
field_length= MAX_INT_WIDTH+sign_len;
913
case DRIZZLE_TYPE_LONGLONG:
914
field_length= MAX_BIGINT_WIDTH;
916
case DRIZZLE_TYPE_NULL:
917
abort(); // Programming error
920
Field* f= make_field(share,
922
record + field_offsets[fieldnr] + data_offset,
924
pfield.constraints().is_nullable(),
930
(Field::utype) MTYP_TYPENR(unireg_type),
931
((field_type == DRIZZLE_TYPE_ENUM) ?
932
share->intervals + (interval_nr++)
934
share->fieldnames.type_names[fieldnr]);
936
share->field[fieldnr]= f;
938
f->init(&temp_table); /* blob default values need table obj */
940
if (! (f->flags & NOT_NULL_FLAG))
942
*f->null_ptr|= f->null_bit;
943
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
950
enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
951
session.count_cuted_fields= CHECK_FIELD_WARN;
952
int res= default_value->save_in_field(f, 1);
953
session.count_cuted_fields= old_count_cuted_fields;
954
if (res != 0 && res != 3) /* @TODO Huh? */
956
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
961
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
962
(f->flags & NOT_NULL_FLAG))
965
f->store((int64_t) 1, true);
970
/* hack to undo f->init() */
974
f->field_index= fieldnr;
976
if (! default_value &&
977
! (f->unireg_check==Field::NEXT_NUMBER) &&
978
(f->flags & NOT_NULL_FLAG) &&
979
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
981
f->flags|= NO_DEFAULT_VALUE_FLAG;
984
if (f->unireg_check == Field::NEXT_NUMBER)
985
share->found_next_number_field= &(share->field[fieldnr]);
987
if (share->timestamp_field == f)
988
share->timestamp_field_offset= fieldnr;
990
if (use_hash) /* supposedly this never fails... but comments lie */
991
(void) my_hash_insert(&share->name_hash,
992
(unsigned char*)&(share->field[fieldnr]));
996
keyinfo= share->key_info;
997
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
999
key_part= keyinfo->key_part;
1001
for (unsigned int partnr= 0;
1002
partnr < keyinfo->key_parts;
1003
partnr++, key_part++)
1006
* Fix up key_part->offset by adding data_offset.
1007
* We really should compute offset as well.
1008
* But at least this way we are a little better.
1010
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1015
We need to set the unused bits to 1. If the number of bits is a multiple
1016
of 8 there are no unused bits.
1020
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1022
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1024
share->last_null_bit_pos= null_bit_pos;
1026
free(field_offsets);
1027
field_offsets= NULL;
1028
free(field_pack_length);
1029
field_pack_length= NULL;
1032
if (share->key_parts)
1034
uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1035
&share->keynames, 3) - 1); /* @TODO Huh? */
1037
keyinfo= share->key_info;
1038
key_part= keyinfo->key_part;
1040
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
1042
uint32_t usable_parts= 0;
1044
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1047
If the UNIQUE key doesn't have NULL columns and is not a part key
1048
declare this as a primary key.
1051
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1053
uint32_t fieldnr= key_part[i].fieldnr;
1055
share->field[fieldnr-1]->null_ptr ||
1056
share->field[fieldnr-1]->key_length() != key_part[i].length)
1058
primary_key= MAX_KEY; // Can't be used
1064
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1067
if (! key_part->fieldnr)
1069
abort(); // goto err;
1071
field= key_part->field= share->field[key_part->fieldnr-1];
1072
key_part->type= field->key_type();
1073
if (field->null_ptr)
1075
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1076
share->default_values);
1077
key_part->null_bit= field->null_bit;
1078
key_part->store_length+=HA_KEY_NULL_LENGTH;
1079
keyinfo->flags|=HA_NULL_PART_KEY;
1080
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1081
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1083
if (field->type() == DRIZZLE_TYPE_BLOB ||
1084
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1086
if (field->type() == DRIZZLE_TYPE_BLOB)
1087
key_part->key_part_flag|= HA_BLOB_PART;
1089
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1090
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1091
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1092
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1094
if (i == 0 && key != primary_key)
1095
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1096
(keyinfo->key_parts == 1)) ?
1097
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1099
field->key_start.set(key);
1100
if (field->key_length() == key_part->length &&
1101
!(field->flags & BLOB_FLAG))
1103
enum ha_key_alg algo= share->key_info[key].algorithm;
1104
if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1106
share->keys_for_keyread.set(key);
1107
field->part_of_key.set(key);
1108
field->part_of_key_not_clustered.set(key);
1110
if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1111
field->part_of_sortkey.set(key);
1113
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1115
usable_parts++; // For FILESORT
1116
field->flags|= PART_KEY_FLAG;
1117
if (key == primary_key)
1119
field->flags|= PRI_KEY_FLAG;
1121
If this field is part of the primary key and all keys contains
1122
the primary key, then we can use any key to find this column
1124
if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1126
field->part_of_key= share->keys_in_use;
1127
if (field->part_of_sortkey.test(key))
1128
field->part_of_sortkey= share->keys_in_use;
1131
if (field->key_length() != key_part->length)
1133
key_part->key_part_flag|= HA_PART_KEY_SEG;
1136
keyinfo->usable_key_parts= usable_parts; // Filesort
1138
set_if_bigger(share->max_key_length,keyinfo->key_length+
1139
keyinfo->key_parts);
1140
share->total_key_length+= keyinfo->key_length;
1142
if (keyinfo->flags & HA_NOSAME)
1144
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1147
if (primary_key < MAX_KEY &&
1148
(share->keys_in_use.test(primary_key)))
1150
share->primary_key= primary_key;
1152
If we are using an integer as the primary key then allow the user to
1153
refer to it as '_rowid'
1155
if (share->key_info[primary_key].key_parts == 1)
1157
Field *field= share->key_info[primary_key].key_part[0].field;
1158
if (field && field->result_type() == INT_RESULT)
1160
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1161
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1167
share->primary_key = MAX_KEY; // we do not have a primary key
1170
share->primary_key= MAX_KEY;
1172
if (share->found_next_number_field)
1174
Field *reg_field= *share->found_next_number_field;
1175
if ((int) (share->next_number_index= (uint32_t)
1176
find_ref_key(share->key_info, share->keys,
1177
share->default_values, reg_field,
1178
&share->next_number_key_offset,
1179
&share->next_number_keypart)) < 0)
1181
/* Wrong field definition */
1186
reg_field->flags |= AUTO_INCREMENT_FLAG;
1189
if (share->blob_fields)
1194
/* Store offsets to blob fields to find them fast */
1195
if (!(share->blob_field= save=
1196
(uint*) alloc_root(&share->mem_root,
1197
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1199
for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1201
if ((*ptr)->flags & BLOB_FLAG)
1206
share->db_low_byte_first= true; // @todo Question this.
1207
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1209
my_bitmap_map *bitmaps;
1211
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1212
share->column_bitmap_size)))
1214
share->all_set.init(bitmaps, share->fields);
1215
share->all_set.setAll();
1221
free(field_offsets);
1222
if (field_pack_length)
1223
free(field_pack_length);
1225
share->error= error;
1226
share->open_errno= errno;
1228
hash_free(&share->name_hash);
1229
share->open_table_error(error, share->open_errno, 0);
1235
Read table definition from a binary / text based .frm cursor
1239
session Thread Cursor
1240
share Fill this with table definition
1243
This function is called when the table definition is not cached in
1245
The data is returned in 'share', which is alloced by
1246
alloc_table_share().. The code assumes that share is initialized.
1250
1 Error (see open_table_error)
1251
2 Error (see open_table_error)
1252
3 Wrong data in .frm cursor
1253
4 Error (see open_table_error)
1254
5 Error (see open_table_error: charset unavailable)
1255
6 Unknown .frm version
1258
int open_table_def(Session& session, TableShare *share)
1266
message::Table table;
1268
error= plugin::StorageEngine::getTableDefinition(session, share->normalized_path.str,
1270
share->table_name.str,
1274
if (error != EEXIST)
1283
if (!table.IsInitialized())
1291
error= parse_table_proto(session, table, share);
1293
share->table_category= get_table_category(& share->db);
1296
session.status_var.opened_shares++;
1299
if (error && !error_given)
1301
share->error= error;
1302
share->open_table_error(error, (share->open_errno= errno), 0);
1310
Open a table based on a TableShare
1313
open_table_from_share()
1314
session Thread Cursor
1315
share Table definition
1316
alias Alias for table
1317
db_stat open flags (for example HA_OPEN_KEYFILE|
1318
HA_OPEN_RNDFILE..) can be 0 (example in
1320
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1321
outparam result table
1325
1 Error (see open_table_error)
1326
2 Error (see open_table_error)
1327
3 Wrong data in .frm cursor
1328
4 Error (see open_table_error)
1329
5 Error (see open_table_error: charset unavailable)
1330
7 Table definition has changed in engine
1333
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1334
uint32_t db_stat, uint32_t ha_open_flags,
1338
uint32_t records, i, bitmap_size;
1339
bool error_reported= false;
1340
unsigned char *record, *bitmaps;
1343
/* Parsing of partitioning information from .frm needs session->lex set up. */
1344
assert(session->lex->is_lex_started);
1347
outparam->resetTable(session, share, db_stat);
1350
if (!(outparam->alias= strdup(alias)))
1353
/* Allocate Cursor */
1354
if (!(outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1359
if ((db_stat & HA_OPEN_KEYFILE))
1364
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1365
share->rec_buff_length * records)))
1370
/* We are probably in hard repair, and the buffers should not be used */
1371
outparam->record[0]= outparam->record[1]= share->default_values;
1375
outparam->record[0]= record;
1377
outparam->record[1]= record+ share->rec_buff_length;
1379
outparam->record[1]= outparam->record[0]; // Safety
1384
We need this because when we read var-length rows, we are not updating
1385
bytes after end of varchar
1389
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1390
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1392
memcpy(outparam->record[1], share->default_values,
1393
share->rec_buff_length);
1397
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1398
(uint32_t) ((share->fields+1)*
1402
outparam->field= field_ptr;
1404
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1406
outparam->null_flags= (unsigned char*) record+1;
1408
/* Setup copy of fields from share, but use the right alias and record */
1409
for (i= 0 ; i < share->fields; i++, field_ptr++)
1411
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1414
(*field_ptr)= 0; // End marker
1416
if (share->found_next_number_field)
1417
outparam->found_next_number_field=
1418
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1419
if (share->timestamp_field)
1420
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1423
/* Fix key->name and key_part->field */
1424
if (share->key_parts)
1426
KEY *key_info, *key_info_end;
1427
KEY_PART_INFO *key_part;
1429
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1430
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1432
outparam->key_info= key_info;
1433
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1435
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1436
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1439
for (key_info_end= key_info + share->keys ;
1440
key_info < key_info_end ;
1443
KEY_PART_INFO *key_part_end;
1445
key_info->table= outparam;
1446
key_info->key_part= key_part;
1448
for (key_part_end= key_part+ key_info->key_parts ;
1449
key_part < key_part_end ;
1452
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1454
if (field->key_length() != key_part->length &&
1455
!(field->flags & BLOB_FLAG))
1458
We are using only a prefix of the column as a key:
1459
Create a new field for the key part that matches the index
1461
field= key_part->field=field->new_field(&outparam->mem_root,
1463
field->field_length= key_part->length;
1469
/* Allocate bitmaps */
1471
bitmap_size= share->column_bitmap_size;
1472
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1474
outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1475
outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1476
outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1477
outparam->default_column_bitmaps();
1479
/* The table struct is now initialized; Open the table */
1484
if ((ha_err= (outparam->cursor->
1485
ha_open(outparam, share->normalized_path.str,
1486
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1487
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1488
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1489
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1490
HA_OPEN_ABORT_IF_LOCKED :
1491
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1495
case HA_ERR_NO_SUCH_TABLE:
1497
The table did not exists in storage engine, use same error message
1498
as if the .frm cursor didn't exist
1505
Too many files opened, use same error message as if the .frm
1512
outparam->print_error(ha_err, MYF(0));
1513
error_reported= true;
1514
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1522
#if defined(HAVE_purify)
1523
memset(bitmaps, 0, bitmap_size*3);
1526
session->status_var.opened_tables++;
1531
if (!error_reported)
1532
share->open_table_error(error, errno, 0);
1533
delete outparam->cursor;
1534
outparam->cursor= 0; // For easier error checking
1535
outparam->db_stat= 0;
1536
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1537
free((char*) outparam->alias);
1541
bool Table::fill_item_list(List<Item> *item_list) const
1544
All Item_field's created using a direct pointer to a field
1545
are fixed in Item_field constructor.
1547
for (Field **ptr= field; *ptr; ptr++)
1549
Item_field *item= new Item_field(*ptr);
1550
if (!item || item_list->push_back(item))
1556
int Table::closefrm(bool free_share)
77
// @note this should all be the destructor
78
int Table::delete_table(bool free_share)
1561
83
error= cursor->close();
1562
free((char*) alias);
1566
87
for (Field **ptr=field ; *ptr ; ptr++)
1571
94
cursor= 0; /* For easier errorchecking */
1574
if (s->tmp_table == NO_TMP_TABLE)
1575
TableShare::release(s);
1577
s->free_table_share();
1579
free_root(&mem_root, MYF(0));
106
mem_root.free_root(MYF(0));
1585
110
void Table::resetTable(Session *session,
1586
111
TableShare *share,
1587
112
uint32_t db_stat_arg)
3018
1398
session->mem_root= mem_root_save;
3019
table->free_tmp_table(session);
3023
1404
/****************************************************************************/
3026
Create a reduced Table object with properly set up Field list from a
3027
list of field definitions.
3029
The created table doesn't have a table Cursor associated with
3030
it, has no keys, no group/distinct, no copy_funcs array.
3031
The sole purpose of this Table object is to use the power of Field
3032
class to read/write data to/from table->record[0]. Then one can store
3033
the record in any container (RB tree, hash, etc).
3034
The table is created in Session mem_root, so are the table's fields.
3035
Consequently, if you don't BLOB fields, you don't need to free it.
3037
@param session connection handle
3038
@param field_list list of column definitions
3041
0 if out of memory, Table object in case of success
3044
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
3046
uint32_t field_count= field_list.elements;
3047
uint32_t blob_count= 0;
3049
CreateField *cdef; /* column definition */
3050
uint32_t record_length= 0;
3051
uint32_t null_count= 0; /* number of columns which may be null */
3052
uint32_t null_pack_length; /* NULL representation array length */
3053
uint32_t *blob_field;
3054
unsigned char *bitmaps;
3058
if (!multi_alloc_root(session->mem_root,
3059
&table, sizeof(*table),
3060
&share, sizeof(*share),
3061
&field, (field_count + 1) * sizeof(Field*),
3062
&blob_field, (field_count+1) *sizeof(uint32_t),
3063
&bitmaps, bitmap_buffer_size(field_count)*2,
3067
memset(table, 0, sizeof(*table));
3068
memset(share, 0, sizeof(*share));
3069
table->field= field;
3071
share->blob_field= blob_field;
3072
share->fields= field_count;
3073
share->blob_ptr_size= portable_sizeof_char_ptr;
3074
table->setup_tmp_table_column_bitmaps(bitmaps);
3076
/* Create all fields and calculate the total length of record */
3077
List_iterator_fast<CreateField> it(field_list);
3078
while ((cdef= it++))
3080
*field= make_field(share,
3084
(cdef->flags & NOT_NULL_FLAG) ? false : true,
3085
(unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
3086
(cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3095
(*field)->init(table);
3096
record_length+= (*field)->pack_length();
3097
if (! ((*field)->flags & NOT_NULL_FLAG))
3100
if ((*field)->flags & BLOB_FLAG)
3101
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
3105
*field= NULL; /* mark the end of the list */
3106
share->blob_field[blob_count]= 0; /* mark the end of the list */
3107
share->blob_fields= blob_count;
3109
null_pack_length= (null_count + 7)/8;
3110
share->reclength= record_length + null_pack_length;
3111
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3112
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
3113
if (!table->record[0])
3116
if (null_pack_length)
3118
table->null_flags= (unsigned char*) table->record[0];
3119
share->null_fields= null_count;
3120
share->null_bytes= null_pack_length;
3123
table->in_use= session; /* field->reset() may access table->in_use */
3125
/* Set up field pointers */
3126
unsigned char *null_pos= table->record[0];
3127
unsigned char *field_pos= null_pos + share->null_bytes;
3128
uint32_t null_bit= 1;
3130
for (field= table->field; *field; ++field)
3132
Field *cur_field= *field;
3133
if ((cur_field->flags & NOT_NULL_FLAG))
3134
cur_field->move_field(field_pos);
3137
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
3139
if (null_bit == (1 << 8))
3147
field_pos+= cur_field->pack_length();
3152
for (field= table->field; *field; ++field)
3153
delete *field; /* just invokes field destructor */
3157
bool Table::open_tmp_table()
3160
if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
3161
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3163
print_error(error, MYF(0));
3167
(void) cursor->extra(HA_EXTRA_QUICK); /* Faster */
3173
Create MyISAM temporary table
3176
create_myisam_tmp_table()
3177
keyinfo Description of the index (there is always one index)
3178
start_recinfo MyISAM's column descriptions
3179
recinfo INOUT End of MyISAM's column descriptions
3183
Create a MyISAM temporary table according to passed description. The is
3184
assumed to have one unique index or constraint.
3186
The passed array or MI_COLUMNDEF structures must have this form:
3188
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
3189
when there are many nullable columns)
3191
3. One free MI_COLUMNDEF element (*recinfo points here)
3193
This function may use the free element to create hash column for unique
3201
bool Table::create_myisam_tmp_table(KEY *keyinfo,
3202
MI_COLUMNDEF *start_recinfo,
3203
MI_COLUMNDEF **recinfo,
3208
MI_UNIQUEDEF uniquedef;
3209
TableShare *share= s;
3212
{ // Get keys for ni_create
3213
bool using_unique_constraint= false;
3214
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3215
sizeof(*seg) * keyinfo->key_parts);
3219
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3220
if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
3221
keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
3224
/* Can't create a key; Make a unique constraint instead of a key */
3227
using_unique_constraint= true;
3228
memset(&uniquedef, 0, sizeof(uniquedef));
3229
uniquedef.keysegs=keyinfo->key_parts;
3231
uniquedef.null_are_equal=1;
3233
/* Create extra column for hash value */
3234
memset(*recinfo, 0, sizeof(**recinfo));
3235
(*recinfo)->type= FIELD_CHECK;
3236
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
3238
share->reclength+=MI_UNIQUE_HASH_LENGTH;
3242
/* Create an unique key */
3243
memset(&keydef, 0, sizeof(keydef));
3244
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
3245
keydef.keysegs= keyinfo->key_parts;
3248
for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
3250
Field *key_field=keyinfo->key_part[i].field;
3252
seg->language= key_field->charset()->number;
3253
seg->length= keyinfo->key_part[i].length;
3254
seg->start= keyinfo->key_part[i].offset;
3255
if (key_field->flags & BLOB_FLAG)
3257
seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
3258
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3259
seg->bit_start= (uint8_t)(key_field->pack_length()
3260
- share->blob_ptr_size);
3261
seg->flag= HA_BLOB_PART;
3262
seg->length= 0; // Whole blob in unique constraint
3266
seg->type= keyinfo->key_part[i].type;
3268
if (!(key_field->flags & NOT_NULL_FLAG))
3270
seg->null_bit= key_field->null_bit;
3271
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
3273
We are using a GROUP BY on something that contains NULL
3274
In this case we have to tell MyISAM that two NULL should
3275
on INSERT be regarded at the same value
3277
if (! using_unique_constraint)
3278
keydef.flag|= HA_NULL_ARE_EQUAL;
3282
MI_CREATE_INFO create_info;
3283
memset(&create_info, 0, sizeof(create_info));
3285
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3287
create_info.data_file_length= ~(uint64_t) 0;
3289
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3290
(uint32_t) (*recinfo-start_recinfo),
3292
share->uniques, &uniquedef,
3294
HA_CREATE_TMP_TABLE)))
3296
print_error(error, MYF(0));
3300
status_var_increment(in_use->status_var.created_tmp_disk_tables);
3301
share->db_record_offset= 1;
3308
void Table::free_tmp_table(Session *session)
3310
memory::Root own_root= mem_root;
3311
const char *save_proc_info;
3313
save_proc_info=session->get_proc_info();
3314
session->set_proc_info("removing tmp table");
3316
// Release latches since this can take a long time
3317
plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3322
cursor->closeMarkForDelete(s->table_name.str);
3324
s->db_type()->doDropTable(*session, s->table_name.str);
3330
for (Field **ptr= field ; *ptr ; ptr++)
3334
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3335
session->set_proc_info(save_proc_info);
3339
If a HEAP table gets full, create a MyISAM table and copy all rows
3343
bool create_myisam_from_heap(Session *session, Table *table,
3344
MI_COLUMNDEF *start_recinfo,
3345
MI_COLUMNDEF **recinfo,
3346
int error, bool ignore_last_dupp_key_error)
3350
const char *save_proc_info;
3353
if (table->s->db_type() != heap_engine ||
3354
error != HA_ERR_RECORD_FILE_FULL)
3356
table->print_error(error, MYF(0));
3360
// Release latches since this can take a long time
3361
plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3365
new_table.s= &share;
3366
new_table.s->storage_engine= myisam_engine;
3367
if (!(new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
3368
return true; // End of memory
3370
save_proc_info=session->get_proc_info();
3371
session->set_proc_info("converting HEAP to MyISAM");
3373
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
3374
recinfo, session->lex->select_lex.options |
3377
if (new_table.open_tmp_table())
3379
if (table->cursor->indexes_are_disabled())
3380
new_table.cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3381
table->cursor->ha_index_or_rnd_end();
3382
table->cursor->ha_rnd_init(1);
3385
new_table.cursor->extra(HA_EXTRA_NO_ROWS);
3386
new_table.no_rows=1;
3389
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3390
new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
3393
copy all old rows from heap table to MyISAM table
3394
This is the only code that uses record[1] to read/write but this
3395
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3397
while (!table->cursor->rnd_next(new_table.record[1]))
3399
write_err= new_table.cursor->ha_write_row(new_table.record[1]);
3403
/* copy row that filled HEAP table */
3404
if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
3406
if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
3407
!ignore_last_dupp_key_error)
3411
/* remove heap table and change to use myisam table */
3412
(void) table->cursor->ha_rnd_end();
3413
(void) table->cursor->close(); // This deletes the table !
3414
delete table->cursor;
3415
table->cursor= NULL;
3416
new_table.s= table->s; // Keep old share
3420
table->cursor->change_table_ptr(table, table->s);
3421
table->use_all_columns();
3424
const char *new_proc_info=
3425
(!strcmp(save_proc_info,"Copying to tmp table") ?
3426
"Copying to tmp table on disk" : save_proc_info);
3427
session->set_proc_info(new_proc_info);
3432
table->print_error(write_err, MYF(0));
3433
(void) table->cursor->ha_rnd_end();
3434
(void) new_table.cursor->close();
3436
new_table.s->db_type()->doDropTable(*session, new_table.s->table_name.str);
3438
delete new_table.cursor;
3439
session->set_proc_info(save_proc_info);
3440
table->mem_root= new_table.mem_root;
3444
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
3446
my_bitmap_map *old= bitmap->getBitmap();
3447
bitmap->setBitmap(s->all_set.getBitmap());
1406
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
boost::dynamic_bitset<>& write_set_arg)
1409
read_set= &read_set_arg;
1410
write_set= &write_set_arg;
1414
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1416
const boost::dynamic_bitset<> old= in_map;
1417
in_map= getShare()->all_set;
3451
void Table::restore_column_map(my_bitmap_map *old)
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
3453
read_set->setBitmap(old);
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
3456
1436
uint32_t Table::find_shortest_key(const key_map *usable_keys)