75
72
/*************************************************************************/
77
// @note this should all be the destructor
78
int Table::delete_table(bool free_share)
74
/* Get column name from column hash */
76
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
78
*length= (uint32_t) strlen((*buff)->field_name);
79
return (unsigned char*) (*buff)->field_name;
82
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
86
if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
87
(my_strcasecmp(system_charset_info,
88
INFORMATION_SCHEMA_NAME.c_str(),
91
return TABLE_CATEGORY_INFORMATION;
94
return TABLE_CATEGORY_USER;
99
Allocate a setup TableShare structure
103
TableList Take database and table name from there
104
key Table cache key (db \0 table_name \0...)
105
key_length Length of key
108
0 Error (out of memory)
112
TableShare *alloc_table_share(TableList *table_list, char *key,
115
memory::Root mem_root;
117
char *key_buff, *path_buff;
118
char path[FN_REFLEN];
119
uint32_t path_length;
121
path_length= build_table_filename(path, sizeof(path) - 1,
123
table_list->table_name, false);
124
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
125
if (multi_alloc_root(&mem_root,
126
&share, sizeof(*share),
127
&key_buff, key_length,
128
&path_buff, path_length + 1,
131
memset(share, 0, sizeof(*share));
133
share->set_table_cache_key(key_buff, key, key_length);
135
share->path.str= path_buff;
136
share->path.length= path_length;
137
strcpy(share->path.str, path);
138
share->normalized_path.str= share->path.str;
139
share->normalized_path.length= path_length;
141
share->version= refresh_version;
143
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
144
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
145
pthread_cond_init(&share->cond, NULL);
151
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
153
enum_field_types field_type;
155
switch(proto_field_type)
157
case message::Table::Field::INTEGER:
158
field_type= DRIZZLE_TYPE_LONG;
160
case message::Table::Field::DOUBLE:
161
field_type= DRIZZLE_TYPE_DOUBLE;
163
case message::Table::Field::TIMESTAMP:
164
field_type= DRIZZLE_TYPE_TIMESTAMP;
166
case message::Table::Field::BIGINT:
167
field_type= DRIZZLE_TYPE_LONGLONG;
169
case message::Table::Field::DATETIME:
170
field_type= DRIZZLE_TYPE_DATETIME;
172
case message::Table::Field::DATE:
173
field_type= DRIZZLE_TYPE_DATE;
175
case message::Table::Field::VARCHAR:
176
field_type= DRIZZLE_TYPE_VARCHAR;
178
case message::Table::Field::DECIMAL:
179
field_type= DRIZZLE_TYPE_DECIMAL;
181
case message::Table::Field::ENUM:
182
field_type= DRIZZLE_TYPE_ENUM;
184
case message::Table::Field::BLOB:
185
field_type= DRIZZLE_TYPE_BLOB;
188
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
195
static Item *default_value_item(enum_field_types field_type,
196
const CHARSET_INFO *charset,
197
bool default_null, const string *default_value,
198
const string *default_bin_value)
200
Item *default_item= NULL;
205
return new Item_null();
210
case DRIZZLE_TYPE_LONG:
211
case DRIZZLE_TYPE_LONGLONG:
212
default_item= new Item_int(default_value->c_str(),
213
(int64_t) internal::my_strtoll10(default_value->c_str(),
216
default_value->length());
218
case DRIZZLE_TYPE_DOUBLE:
219
default_item= new Item_float(default_value->c_str(),
220
default_value->length());
222
case DRIZZLE_TYPE_NULL:
224
case DRIZZLE_TYPE_TIMESTAMP:
225
case DRIZZLE_TYPE_DATETIME:
226
case DRIZZLE_TYPE_DATE:
227
if (default_value->compare("NOW()") == 0)
229
case DRIZZLE_TYPE_ENUM:
230
default_item= new Item_string(default_value->c_str(),
231
default_value->length(),
232
system_charset_info);
234
case DRIZZLE_TYPE_VARCHAR:
235
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
236
if (charset==&my_charset_bin)
238
default_item= new Item_string(default_bin_value->c_str(),
239
default_bin_value->length(),
244
default_item= new Item_string(default_value->c_str(),
245
default_value->length(),
246
system_charset_info);
249
case DRIZZLE_TYPE_DECIMAL:
250
default_item= new Item_decimal(default_value->c_str(),
251
default_value->length(),
252
system_charset_info);
259
int parse_table_proto(Session& session,
260
message::Table &table,
265
if (! table.IsInitialized())
267
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
268
return ER_CORRUPT_TABLE_DEFINITION;
271
share->setTableProto(new(nothrow) message::Table(table));
273
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
274
assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
276
message::Table::TableOptions table_options;
278
if (table.has_options())
279
table_options= table.options();
281
uint32_t db_create_options= 0;
283
if (table_options.has_pack_keys())
285
if (table_options.pack_keys())
286
db_create_options|= HA_OPTION_PACK_KEYS;
288
db_create_options|= HA_OPTION_NO_PACK_KEYS;
291
if (table_options.pack_record())
292
db_create_options|= HA_OPTION_PACK_RECORD;
294
/* db_create_options was stored as 2 bytes in FRM
295
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
297
share->db_create_options= (db_create_options & 0x0000FFFF);
298
share->db_options_in_use= share->db_create_options;
300
share->row_type= table_options.has_row_type() ?
301
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
303
share->block_size= table_options.has_block_size() ?
304
table_options.block_size() : 0;
306
share->table_charset= get_charset(table_options.has_collation_id()?
307
table_options.collation_id() : 0);
309
if (!share->table_charset)
311
/* unknown charset in head[38] or pre-3.23 frm */
312
if (use_mb(default_charset_info))
314
/* Warn that we may be changing the size of character columns */
315
errmsg_printf(ERRMSG_LVL_WARN,
316
_("'%s' had no or invalid character set, "
317
"and default character set is multi-byte, "
318
"so character column sizes may have changed"),
321
share->table_charset= default_charset_info;
324
share->db_record_offset= 1;
326
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
328
share->keys= table.indexes_size();
331
for (int indx= 0; indx < table.indexes_size(); indx++)
332
share->key_parts+= table.indexes(indx).index_part_size();
334
share->key_info= (KEY*) alloc_root(&share->mem_root,
335
table.indexes_size() * sizeof(KEY)
336
+share->key_parts*sizeof(KEY_PART_INFO));
338
KEY_PART_INFO *key_part;
340
key_part= reinterpret_cast<KEY_PART_INFO*>
341
(share->key_info+table.indexes_size());
344
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
345
sizeof(ulong*)*share->key_parts);
347
share->keynames.count= table.indexes_size();
348
share->keynames.name= NULL;
349
share->keynames.type_names= (const char**)
350
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
352
share->keynames.type_lengths= (unsigned int*)
353
alloc_root(&share->mem_root,
354
sizeof(unsigned int) * (table.indexes_size()+1));
356
share->keynames.type_names[share->keynames.count]= NULL;
357
share->keynames.type_lengths[share->keynames.count]= 0;
359
KEY* keyinfo= share->key_info;
360
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
362
message::Table::Index indx= table.indexes(keynr);
367
if (indx.is_unique())
368
keyinfo->flags|= HA_NOSAME;
370
if (indx.has_options())
372
message::Table::Index::IndexOptions indx_options= indx.options();
373
if (indx_options.pack_key())
374
keyinfo->flags|= HA_PACK_KEY;
376
if (indx_options.var_length_key())
377
keyinfo->flags|= HA_VAR_LENGTH_PART;
379
if (indx_options.null_part_key())
380
keyinfo->flags|= HA_NULL_PART_KEY;
382
if (indx_options.binary_pack_key())
383
keyinfo->flags|= HA_BINARY_PACK_KEY;
385
if (indx_options.has_partial_segments())
386
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
388
if (indx_options.auto_generated_key())
389
keyinfo->flags|= HA_GENERATED_KEY;
391
if (indx_options.has_key_block_size())
393
keyinfo->flags|= HA_USES_BLOCK_SIZE;
394
keyinfo->block_size= indx_options.key_block_size();
398
keyinfo->block_size= 0;
404
case message::Table::Index::UNKNOWN_INDEX:
405
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
407
case message::Table::Index::BTREE:
408
keyinfo->algorithm= HA_KEY_ALG_BTREE;
410
case message::Table::Index::HASH:
411
keyinfo->algorithm= HA_KEY_ALG_HASH;
415
/* TODO: suitable warning ? */
416
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
420
keyinfo->key_length= indx.key_length();
422
keyinfo->key_parts= indx.index_part_size();
424
keyinfo->key_part= key_part;
425
keyinfo->rec_per_key= rec_per_key;
427
for (unsigned int partnr= 0;
428
partnr < keyinfo->key_parts;
429
partnr++, key_part++)
431
message::Table::Index::IndexPart part;
432
part= indx.index_part(partnr);
436
key_part->field= NULL;
437
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
438
key_part->null_bit= 0;
439
/* key_part->null_offset is only set if null_bit (see later) */
440
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
441
/* key_part->type ???? */
442
key_part->key_part_flag= 0;
443
if (part.has_in_reverse_order())
444
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
446
key_part->length= part.compare_length();
448
key_part->store_length= key_part->length;
450
/* key_part->offset is set later */
451
key_part->key_type= part.key_type();
454
if (! indx.has_comment())
456
keyinfo->comment.length= 0;
457
keyinfo->comment.str= NULL;
461
keyinfo->flags|= HA_USES_COMMENT;
462
keyinfo->comment.length= indx.comment().length();
463
keyinfo->comment.str= strmake_root(&share->mem_root,
464
indx.comment().c_str(),
465
keyinfo->comment.length);
468
keyinfo->name= strmake_root(&share->mem_root,
470
indx.name().length());
472
share->keynames.type_names[keynr]= keyinfo->name;
473
share->keynames.type_lengths[keynr]= indx.name().length();
476
share->keys_for_keyread.reset();
477
set_prefix(share->keys_in_use, share->keys);
479
share->fields= table.field_size();
481
share->field= (Field**) alloc_root(&share->mem_root,
482
((share->fields+1) * sizeof(Field*)));
483
share->field[share->fields]= NULL;
485
uint32_t null_fields= 0;
488
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
489
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
491
assert(field_offsets && field_pack_length); // TODO: fixme
493
uint32_t interval_count= 0;
494
uint32_t interval_parts= 0;
496
uint32_t stored_columns_reclength= 0;
498
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
500
message::Table::Field pfield= table.field(fieldnr);
501
if (pfield.constraints().is_nullable())
504
enum_field_types drizzle_field_type=
505
proto_field_type_to_drizzle_type(pfield.type());
507
field_offsets[fieldnr]= stored_columns_reclength;
509
/* the below switch is very similar to
510
CreateField::create_length_to_internal_length in field.cc
511
(which should one day be replace by just this code)
513
switch(drizzle_field_type)
515
case DRIZZLE_TYPE_BLOB:
516
case DRIZZLE_TYPE_VARCHAR:
518
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
520
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
521
field_options.collation_id() : 0);
524
cs= default_charset_info;
526
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
527
field_options.length() * cs->mbmaxlen);
530
case DRIZZLE_TYPE_ENUM:
532
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
534
field_pack_length[fieldnr]=
535
get_enum_pack_length(field_options.field_value_size());
538
interval_parts+= field_options.field_value_size();
541
case DRIZZLE_TYPE_DECIMAL:
543
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
545
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
549
/* Zero is okay here as length is fixed for other types. */
550
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
553
share->reclength+= field_pack_length[fieldnr];
554
stored_columns_reclength+= field_pack_length[fieldnr];
557
/* data_offset added to stored_rec_length later */
558
share->stored_rec_length= stored_columns_reclength;
560
share->null_fields= null_fields;
562
ulong null_bits= null_fields;
563
if (! table_options.pack_record())
565
ulong data_offset= (null_bits + 7)/8;
568
share->reclength+= data_offset;
569
share->stored_rec_length+= data_offset;
571
ulong rec_buff_length;
573
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
574
share->rec_buff_length= rec_buff_length;
576
unsigned char* record= NULL;
578
if (! (record= (unsigned char *) alloc_root(&share->mem_root,
582
memset(record, 0, rec_buff_length);
586
if (! table_options.pack_record())
588
null_count++; // one bit for delete mark.
592
share->default_values= record;
596
share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
597
interval_count*sizeof(TYPELIB));
600
share->intervals= NULL;
602
share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
603
(share->fields + 1) * sizeof(char*));
605
share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
606
(share->fields + 1) * sizeof(unsigned int));
608
share->fieldnames.type_names[share->fields]= NULL;
609
share->fieldnames.type_lengths[share->fields]= 0;
610
share->fieldnames.count= share->fields;
613
/* Now fix the TYPELIBs for the intervals (enum values)
617
uint32_t interval_nr= 0;
619
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
621
message::Table::Field pfield= table.field(fieldnr);
624
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
625
pfield.name().c_str(),
626
pfield.name().length());
628
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
631
if (pfield.type() != message::Table::Field::ENUM)
634
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
636
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
637
field_options.collation_id() : 0);
640
charset= default_charset_info;
642
TYPELIB *t= &(share->intervals[interval_nr]);
644
t->type_names= (const char**)alloc_root(&share->mem_root,
645
(field_options.field_value_size() + 1) * sizeof(char*));
647
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
648
(field_options.field_value_size() + 1) * sizeof(unsigned int));
650
t->type_names[field_options.field_value_size()]= NULL;
651
t->type_lengths[field_options.field_value_size()]= 0;
653
t->count= field_options.field_value_size();
656
for (int n= 0; n < field_options.field_value_size(); n++)
658
t->type_names[n]= strmake_root(&share->mem_root,
659
field_options.field_value(n).c_str(),
660
field_options.field_value(n).length());
663
* Go ask the charset what the length is as for "" length=1
664
* and there's stripping spaces or some other crack going on.
667
lengthsp= charset->cset->lengthsp(charset,
669
field_options.field_value(n).length());
670
t->type_lengths[n]= lengthsp;
676
/* and read the fields */
679
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
682
use_hash= ! hash_init(&share->name_hash,
687
(hash_get_key) get_field_name,
691
unsigned char* null_pos= record;;
692
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
694
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
696
message::Table::Field pfield= table.field(fieldnr);
698
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
700
switch (pfield.format())
702
case message::Table::Field::DefaultFormat:
703
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
705
case message::Table::Field::FixedFormat:
706
column_format= COLUMN_FORMAT_TYPE_FIXED;
708
case message::Table::Field::DynamicFormat:
709
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
715
Field::utype unireg_type= Field::NONE;
717
if (pfield.has_numeric_options() &&
718
pfield.numeric_options().is_autoincrement())
720
unireg_type= Field::NEXT_NUMBER;
723
if (pfield.has_options() &&
724
pfield.options().has_default_value() &&
725
pfield.options().default_value().compare("NOW()") == 0)
727
if (pfield.options().has_update_value() &&
728
pfield.options().update_value().compare("NOW()") == 0)
730
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
732
else if (! pfield.options().has_update_value())
734
unireg_type= Field::TIMESTAMP_DN_FIELD;
737
assert(1); // Invalid update value.
739
else if (pfield.has_options() &&
740
pfield.options().has_update_value() &&
741
pfield.options().update_value().compare("NOW()") == 0)
743
unireg_type= Field::TIMESTAMP_UN_FIELD;
747
if (!pfield.has_comment())
749
comment.str= (char*)"";
754
size_t len= pfield.comment().length();
755
const char* str= pfield.comment().c_str();
757
comment.str= strmake_root(&share->mem_root, str, len);
761
enum_field_types field_type;
763
field_type= proto_field_type_to_drizzle_type(pfield.type());
765
const CHARSET_INFO *charset= &my_charset_bin;
767
if (field_type == DRIZZLE_TYPE_BLOB ||
768
field_type == DRIZZLE_TYPE_VARCHAR)
770
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
772
charset= get_charset(field_options.has_collation_id() ?
773
field_options.collation_id() : 0);
776
charset= default_charset_info;
779
if (field_type == DRIZZLE_TYPE_ENUM)
781
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
783
charset= get_charset(field_options.has_collation_id()?
784
field_options.collation_id() : 0);
787
charset= default_charset_info;
791
if (field_type == DRIZZLE_TYPE_DECIMAL
792
|| field_type == DRIZZLE_TYPE_DOUBLE)
794
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
796
if (! pfield.has_numeric_options() || ! fo.has_scale())
799
We don't write the default to table proto so
800
if no decimals specified for DOUBLE, we use the default.
802
decimals= NOT_FIXED_DEC;
806
if (fo.scale() > DECIMAL_MAX_SCALE)
811
decimals= static_cast<uint8_t>(fo.scale());
815
Item *default_value= NULL;
817
if (pfield.options().has_default_value() ||
818
pfield.options().has_default_null() ||
819
pfield.options().has_default_bin_value())
821
default_value= default_value_item(field_type,
823
pfield.options().default_null(),
824
&pfield.options().default_value(),
825
&pfield.options().default_bin_value());
829
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
830
memset(&temp_table, 0, sizeof(temp_table));
832
temp_table.in_use= &session;
833
temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
834
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
836
uint32_t field_length= 0; //Assignment is for compiler complaint.
840
case DRIZZLE_TYPE_BLOB:
841
case DRIZZLE_TYPE_VARCHAR:
843
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
845
charset= get_charset(field_options.has_collation_id() ?
846
field_options.collation_id() : 0);
849
charset= default_charset_info;
851
field_length= field_options.length() * charset->mbmaxlen;
854
case DRIZZLE_TYPE_DOUBLE:
856
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
857
if (!fo.has_precision() && !fo.has_scale())
859
field_length= DBL_DIG+7;
863
field_length= fo.precision();
865
if (field_length < decimals &&
866
decimals != NOT_FIXED_DEC)
868
my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
874
case DRIZZLE_TYPE_DECIMAL:
876
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
878
field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
882
case DRIZZLE_TYPE_TIMESTAMP:
883
case DRIZZLE_TYPE_DATETIME:
884
field_length= DateTime::MAX_STRING_LENGTH;
886
case DRIZZLE_TYPE_DATE:
887
field_length= Date::MAX_STRING_LENGTH;
889
case DRIZZLE_TYPE_ENUM:
893
message::Table::Field::SetFieldOptions fo= pfield.set_options();
895
for(int valnr= 0; valnr < fo.field_value_size(); valnr++)
897
if (fo.field_value(valnr).length() > field_length)
898
field_length= charset->cset->numchars(charset,
899
fo.field_value(valnr).c_str(),
900
fo.field_value(valnr).c_str()
901
+ fo.field_value(valnr).length())
906
case DRIZZLE_TYPE_LONG:
908
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
909
field_length= MAX_INT_WIDTH+sign_len;
912
case DRIZZLE_TYPE_LONGLONG:
913
field_length= MAX_BIGINT_WIDTH;
915
case DRIZZLE_TYPE_NULL:
916
abort(); // Programming error
919
Field* f= make_field(share,
921
record + field_offsets[fieldnr] + data_offset,
923
pfield.constraints().is_nullable(),
929
(Field::utype) MTYP_TYPENR(unireg_type),
930
((field_type == DRIZZLE_TYPE_ENUM) ?
931
share->intervals + (interval_nr++)
933
share->fieldnames.type_names[fieldnr]);
935
share->field[fieldnr]= f;
937
f->init(&temp_table); /* blob default values need table obj */
939
if (! (f->flags & NOT_NULL_FLAG))
941
*f->null_ptr|= f->null_bit;
942
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
949
enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
950
session.count_cuted_fields= CHECK_FIELD_WARN;
951
int res= default_value->save_in_field(f, 1);
952
session.count_cuted_fields= old_count_cuted_fields;
953
if (res != 0 && res != 3) /* @TODO Huh? */
955
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
960
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
961
(f->flags & NOT_NULL_FLAG))
964
f->store((int64_t) 1, true);
969
/* hack to undo f->init() */
973
f->field_index= fieldnr;
975
if (! default_value &&
976
! (f->unireg_check==Field::NEXT_NUMBER) &&
977
(f->flags & NOT_NULL_FLAG) &&
978
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
980
f->flags|= NO_DEFAULT_VALUE_FLAG;
983
if (f->unireg_check == Field::NEXT_NUMBER)
984
share->found_next_number_field= &(share->field[fieldnr]);
986
if (share->timestamp_field == f)
987
share->timestamp_field_offset= fieldnr;
989
if (use_hash) /* supposedly this never fails... but comments lie */
990
(void) my_hash_insert(&share->name_hash,
991
(unsigned char*)&(share->field[fieldnr]));
995
keyinfo= share->key_info;
996
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
998
key_part= keyinfo->key_part;
1000
for (unsigned int partnr= 0;
1001
partnr < keyinfo->key_parts;
1002
partnr++, key_part++)
1005
* Fix up key_part->offset by adding data_offset.
1006
* We really should compute offset as well.
1007
* But at least this way we are a little better.
1009
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1014
We need to set the unused bits to 1. If the number of bits is a multiple
1015
of 8 there are no unused bits.
1019
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1021
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1023
share->last_null_bit_pos= null_bit_pos;
1025
free(field_offsets);
1026
field_offsets= NULL;
1027
free(field_pack_length);
1028
field_pack_length= NULL;
1031
if (share->key_parts)
1033
uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1034
&share->keynames, 3) - 1); /* @TODO Huh? */
1036
keyinfo= share->key_info;
1037
key_part= keyinfo->key_part;
1039
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
1041
uint32_t usable_parts= 0;
1043
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1046
If the UNIQUE key doesn't have NULL columns and is not a part key
1047
declare this as a primary key.
1050
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1052
uint32_t fieldnr= key_part[i].fieldnr;
1054
share->field[fieldnr-1]->null_ptr ||
1055
share->field[fieldnr-1]->key_length() != key_part[i].length)
1057
primary_key= MAX_KEY; // Can't be used
1063
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1066
if (! key_part->fieldnr)
1068
abort(); // goto err;
1070
field= key_part->field= share->field[key_part->fieldnr-1];
1071
key_part->type= field->key_type();
1072
if (field->null_ptr)
1074
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1075
share->default_values);
1076
key_part->null_bit= field->null_bit;
1077
key_part->store_length+=HA_KEY_NULL_LENGTH;
1078
keyinfo->flags|=HA_NULL_PART_KEY;
1079
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1080
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1082
if (field->type() == DRIZZLE_TYPE_BLOB ||
1083
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1085
if (field->type() == DRIZZLE_TYPE_BLOB)
1086
key_part->key_part_flag|= HA_BLOB_PART;
1088
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1089
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1090
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1091
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1093
if (i == 0 && key != primary_key)
1094
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1095
(keyinfo->key_parts == 1)) ?
1096
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1098
field->key_start.set(key);
1099
if (field->key_length() == key_part->length &&
1100
!(field->flags & BLOB_FLAG))
1102
enum ha_key_alg algo= share->key_info[key].algorithm;
1103
if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1105
share->keys_for_keyread.set(key);
1106
field->part_of_key.set(key);
1107
field->part_of_key_not_clustered.set(key);
1109
if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1110
field->part_of_sortkey.set(key);
1112
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1114
usable_parts++; // For FILESORT
1115
field->flags|= PART_KEY_FLAG;
1116
if (key == primary_key)
1118
field->flags|= PRI_KEY_FLAG;
1120
If this field is part of the primary key and all keys contains
1121
the primary key, then we can use any key to find this column
1123
if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1125
field->part_of_key= share->keys_in_use;
1126
if (field->part_of_sortkey.test(key))
1127
field->part_of_sortkey= share->keys_in_use;
1130
if (field->key_length() != key_part->length)
1132
key_part->key_part_flag|= HA_PART_KEY_SEG;
1135
keyinfo->usable_key_parts= usable_parts; // Filesort
1137
set_if_bigger(share->max_key_length,keyinfo->key_length+
1138
keyinfo->key_parts);
1139
share->total_key_length+= keyinfo->key_length;
1141
if (keyinfo->flags & HA_NOSAME)
1143
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1146
if (primary_key < MAX_KEY &&
1147
(share->keys_in_use.test(primary_key)))
1149
share->primary_key= primary_key;
1151
If we are using an integer as the primary key then allow the user to
1152
refer to it as '_rowid'
1154
if (share->key_info[primary_key].key_parts == 1)
1156
Field *field= share->key_info[primary_key].key_part[0].field;
1157
if (field && field->result_type() == INT_RESULT)
1159
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1160
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1166
share->primary_key = MAX_KEY; // we do not have a primary key
1169
share->primary_key= MAX_KEY;
1171
if (share->found_next_number_field)
1173
Field *reg_field= *share->found_next_number_field;
1174
if ((int) (share->next_number_index= (uint32_t)
1175
find_ref_key(share->key_info, share->keys,
1176
share->default_values, reg_field,
1177
&share->next_number_key_offset,
1178
&share->next_number_keypart)) < 0)
1180
/* Wrong field definition */
1185
reg_field->flags |= AUTO_INCREMENT_FLAG;
1188
if (share->blob_fields)
1193
/* Store offsets to blob fields to find them fast */
1194
if (!(share->blob_field= save=
1195
(uint*) alloc_root(&share->mem_root,
1196
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1198
for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1200
if ((*ptr)->flags & BLOB_FLAG)
1205
share->db_low_byte_first= true; // @todo Question this.
1206
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1208
my_bitmap_map *bitmaps;
1210
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1211
share->column_bitmap_size)))
1213
share->all_set.init(bitmaps, share->fields);
1214
share->all_set.setAll();
1220
free(field_offsets);
1221
if (field_pack_length)
1222
free(field_pack_length);
1224
share->error= error;
1225
share->open_errno= errno;
1227
hash_free(&share->name_hash);
1228
share->open_table_error(error, share->open_errno, 0);
1234
Read table definition from a binary / text based .frm cursor
1238
session Thread Cursor
1239
share Fill this with table definition
1242
This function is called when the table definition is not cached in
1244
The data is returned in 'share', which is alloced by
1245
alloc_table_share().. The code assumes that share is initialized.
1249
1 Error (see open_table_error)
1250
2 Error (see open_table_error)
1251
3 Wrong data in .frm cursor
1252
4 Error (see open_table_error)
1253
5 Error (see open_table_error: charset unavailable)
1254
6 Unknown .frm version
1257
int open_table_def(Session& session, TableShare *share)
1265
message::Table table;
1267
error= plugin::StorageEngine::getTableDefinition(session, share->normalized_path.str,
1269
share->table_name.str,
1273
if (error != EEXIST)
1282
if (!table.IsInitialized())
1290
error= parse_table_proto(session, table, share);
1292
share->table_category= get_table_category(& share->db);
1295
session.status_var.opened_shares++;
1298
if (error && !error_given)
1300
share->error= error;
1301
share->open_table_error(error, (share->open_errno= errno), 0);
1309
Open a table based on a TableShare
1312
open_table_from_share()
1313
session Thread Cursor
1314
share Table definition
1315
alias Alias for table
1316
db_stat open flags (for example HA_OPEN_KEYFILE|
1317
HA_OPEN_RNDFILE..) can be 0 (example in
1319
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1320
outparam result table
1324
1 Error (see open_table_error)
1325
2 Error (see open_table_error)
1326
3 Wrong data in .frm cursor
1327
4 Error (see open_table_error)
1328
5 Error (see open_table_error: charset unavailable)
1329
7 Table definition has changed in engine
1332
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1333
uint32_t db_stat, uint32_t ha_open_flags,
1337
uint32_t records, i, bitmap_size;
1338
bool error_reported= false;
1339
unsigned char *record, *bitmaps;
1342
/* Parsing of partitioning information from .frm needs session->lex set up. */
1343
assert(session->lex->is_lex_started);
1346
outparam->resetTable(session, share, db_stat);
1349
if (!(outparam->alias= strdup(alias)))
1352
/* Allocate Cursor */
1353
if (!(outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1358
if ((db_stat & HA_OPEN_KEYFILE))
1363
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1364
share->rec_buff_length * records)))
1369
/* We are probably in hard repair, and the buffers should not be used */
1370
outparam->record[0]= outparam->record[1]= share->default_values;
1374
outparam->record[0]= record;
1376
outparam->record[1]= record+ share->rec_buff_length;
1378
outparam->record[1]= outparam->record[0]; // Safety
1383
We need this because when we read var-length rows, we are not updating
1384
bytes after end of varchar
1388
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1389
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1391
memcpy(outparam->record[1], share->default_values,
1392
share->rec_buff_length);
1396
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1397
(uint32_t) ((share->fields+1)*
1401
outparam->field= field_ptr;
1403
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1405
outparam->null_flags= (unsigned char*) record+1;
1407
/* Setup copy of fields from share, but use the right alias and record */
1408
for (i= 0 ; i < share->fields; i++, field_ptr++)
1410
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1413
(*field_ptr)= 0; // End marker
1415
if (share->found_next_number_field)
1416
outparam->found_next_number_field=
1417
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1418
if (share->timestamp_field)
1419
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1422
/* Fix key->name and key_part->field */
1423
if (share->key_parts)
1425
KEY *key_info, *key_info_end;
1426
KEY_PART_INFO *key_part;
1428
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1429
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1431
outparam->key_info= key_info;
1432
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1434
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1435
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1438
for (key_info_end= key_info + share->keys ;
1439
key_info < key_info_end ;
1442
KEY_PART_INFO *key_part_end;
1444
key_info->table= outparam;
1445
key_info->key_part= key_part;
1447
for (key_part_end= key_part+ key_info->key_parts ;
1448
key_part < key_part_end ;
1451
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1453
if (field->key_length() != key_part->length &&
1454
!(field->flags & BLOB_FLAG))
1457
We are using only a prefix of the column as a key:
1458
Create a new field for the key part that matches the index
1460
field= key_part->field=field->new_field(&outparam->mem_root,
1462
field->field_length= key_part->length;
1468
/* Allocate bitmaps */
1470
bitmap_size= share->column_bitmap_size;
1471
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1473
outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1474
outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1475
outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1476
outparam->default_column_bitmaps();
1478
/* The table struct is now initialized; Open the table */
1483
if ((ha_err= (outparam->cursor->
1484
ha_open(outparam, share->normalized_path.str,
1485
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1486
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1487
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1488
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1489
HA_OPEN_ABORT_IF_LOCKED :
1490
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1494
case HA_ERR_NO_SUCH_TABLE:
1496
The table did not exists in storage engine, use same error message
1497
as if the .frm cursor didn't exist
1504
Too many files opened, use same error message as if the .frm
1511
outparam->print_error(ha_err, MYF(0));
1512
error_reported= true;
1513
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1521
#if defined(HAVE_purify)
1522
memset(bitmaps, 0, bitmap_size*3);
1525
session->status_var.opened_tables++;
1530
if (!error_reported)
1531
share->open_table_error(error, errno, 0);
1532
delete outparam->cursor;
1533
outparam->cursor= 0; // For easier error checking
1534
outparam->db_stat= 0;
1535
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1536
free((char*) outparam->alias);
1540
bool Table::fill_item_list(List<Item> *item_list) const
1543
All Item_field's created using a direct pointer to a field
1544
are fixed in Item_field constructor.
1546
for (Field **ptr= field; *ptr; ptr++)
1548
Item_field *item= new Item_field(*ptr);
1549
if (!item || item_list->push_back(item))
1555
int Table::closefrm(bool free_share)
83
1560
error= cursor->close();
1561
free((char*) alias);
87
1565
for (Field **ptr=field ; *ptr ; ptr++)
94
1570
cursor= 0; /* For easier errorchecking */
1573
if (s->tmp_table == NO_TMP_TABLE)
1574
TableShare::release(s);
1576
s->free_table_share();
1578
free_root(&mem_root, MYF(0));
106
mem_root.free_root(MYF(0));
110
1584
void Table::resetTable(Session *session,
111
1585
TableShare *share,
112
1586
uint32_t db_stat_arg)
1398
3021
session->mem_root= mem_root_save;
3022
table->free_tmp_table(session);
1404
3026
/****************************************************************************/
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;
3029
Create a reduced Table object with properly set up Field list from a
3030
list of field definitions.
3032
The created table doesn't have a table Cursor associated with
3033
it, has no keys, no group/distinct, no copy_funcs array.
3034
The sole purpose of this Table object is to use the power of Field
3035
class to read/write data to/from table->record[0]. Then one can store
3036
the record in any container (RB tree, hash, etc).
3037
The table is created in Session mem_root, so are the table's fields.
3038
Consequently, if you don't BLOB fields, you don't need to free it.
3040
@param session connection handle
3041
@param field_list list of column definitions
3044
0 if out of memory, Table object in case of success
3047
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
3049
uint32_t field_count= field_list.elements;
3050
uint32_t blob_count= 0;
3052
CreateField *cdef; /* column definition */
3053
uint32_t record_length= 0;
3054
uint32_t null_count= 0; /* number of columns which may be null */
3055
uint32_t null_pack_length; /* NULL representation array length */
3056
uint32_t *blob_field;
3057
unsigned char *bitmaps;
3061
if (!multi_alloc_root(session->mem_root,
3062
&table, sizeof(*table),
3063
&share, sizeof(*share),
3064
&field, (field_count + 1) * sizeof(Field*),
3065
&blob_field, (field_count+1) *sizeof(uint32_t),
3066
&bitmaps, bitmap_buffer_size(field_count)*2,
3070
memset(table, 0, sizeof(*table));
3071
memset(share, 0, sizeof(*share));
3072
table->field= field;
3074
share->blob_field= blob_field;
3075
share->fields= field_count;
3076
share->blob_ptr_size= portable_sizeof_char_ptr;
3077
table->setup_tmp_table_column_bitmaps(bitmaps);
3079
/* Create all fields and calculate the total length of record */
3080
List_iterator_fast<CreateField> it(field_list);
3081
while ((cdef= it++))
3083
*field= make_field(share,
3087
(cdef->flags & NOT_NULL_FLAG) ? false : true,
3088
(unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
3089
(cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3098
(*field)->init(table);
3099
record_length+= (*field)->pack_length();
3100
if (! ((*field)->flags & NOT_NULL_FLAG))
3103
if ((*field)->flags & BLOB_FLAG)
3104
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
3108
*field= NULL; /* mark the end of the list */
3109
share->blob_field[blob_count]= 0; /* mark the end of the list */
3110
share->blob_fields= blob_count;
3112
null_pack_length= (null_count + 7)/8;
3113
share->reclength= record_length + null_pack_length;
3114
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3115
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
3116
if (!table->record[0])
3119
if (null_pack_length)
3121
table->null_flags= (unsigned char*) table->record[0];
3122
share->null_fields= null_count;
3123
share->null_bytes= null_pack_length;
3126
table->in_use= session; /* field->reset() may access table->in_use */
3128
/* Set up field pointers */
3129
unsigned char *null_pos= table->record[0];
3130
unsigned char *field_pos= null_pos + share->null_bytes;
3131
uint32_t null_bit= 1;
3133
for (field= table->field; *field; ++field)
3135
Field *cur_field= *field;
3136
if ((cur_field->flags & NOT_NULL_FLAG))
3137
cur_field->move_field(field_pos);
3140
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
3142
if (null_bit == (1 << 8))
3150
field_pos+= cur_field->pack_length();
3155
for (field= table->field; *field; ++field)
3156
delete *field; /* just invokes field destructor */
3160
bool Table::open_tmp_table()
3163
if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
3164
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3166
print_error(error, MYF(0));
3170
(void) cursor->extra(HA_EXTRA_QUICK); /* Faster */
3176
Create MyISAM temporary table
3179
create_myisam_tmp_table()
3180
keyinfo Description of the index (there is always one index)
3181
start_recinfo MyISAM's column descriptions
3182
recinfo INOUT End of MyISAM's column descriptions
3186
Create a MyISAM temporary table according to passed description. The is
3187
assumed to have one unique index or constraint.
3189
The passed array or MI_COLUMNDEF structures must have this form:
3191
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
3192
when there are many nullable columns)
3194
3. One free MI_COLUMNDEF element (*recinfo points here)
3196
This function may use the free element to create hash column for unique
3204
bool Table::create_myisam_tmp_table(KEY *keyinfo,
3205
MI_COLUMNDEF *start_recinfo,
3206
MI_COLUMNDEF **recinfo,
3211
MI_UNIQUEDEF uniquedef;
3212
TableShare *share= s;
3215
{ // Get keys for ni_create
3216
bool using_unique_constraint= false;
3217
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3218
sizeof(*seg) * keyinfo->key_parts);
3222
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3223
if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
3224
keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
3227
/* Can't create a key; Make a unique constraint instead of a key */
3230
using_unique_constraint= true;
3231
memset(&uniquedef, 0, sizeof(uniquedef));
3232
uniquedef.keysegs=keyinfo->key_parts;
3234
uniquedef.null_are_equal=1;
3236
/* Create extra column for hash value */
3237
memset(*recinfo, 0, sizeof(**recinfo));
3238
(*recinfo)->type= FIELD_CHECK;
3239
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
3241
share->reclength+=MI_UNIQUE_HASH_LENGTH;
3245
/* Create an unique key */
3246
memset(&keydef, 0, sizeof(keydef));
3247
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
3248
keydef.keysegs= keyinfo->key_parts;
3251
for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
3253
Field *key_field=keyinfo->key_part[i].field;
3255
seg->language= key_field->charset()->number;
3256
seg->length= keyinfo->key_part[i].length;
3257
seg->start= keyinfo->key_part[i].offset;
3258
if (key_field->flags & BLOB_FLAG)
3260
seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
3261
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3262
seg->bit_start= (uint8_t)(key_field->pack_length()
3263
- share->blob_ptr_size);
3264
seg->flag= HA_BLOB_PART;
3265
seg->length= 0; // Whole blob in unique constraint
3269
seg->type= keyinfo->key_part[i].type;
3271
if (!(key_field->flags & NOT_NULL_FLAG))
3273
seg->null_bit= key_field->null_bit;
3274
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
3276
We are using a GROUP BY on something that contains NULL
3277
In this case we have to tell MyISAM that two NULL should
3278
on INSERT be regarded at the same value
3280
if (! using_unique_constraint)
3281
keydef.flag|= HA_NULL_ARE_EQUAL;
3285
MI_CREATE_INFO create_info;
3286
memset(&create_info, 0, sizeof(create_info));
3288
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3290
create_info.data_file_length= ~(uint64_t) 0;
3292
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3293
(uint32_t) (*recinfo-start_recinfo),
3295
share->uniques, &uniquedef,
3297
HA_CREATE_TMP_TABLE)))
3299
print_error(error, MYF(0));
3303
status_var_increment(in_use->status_var.created_tmp_disk_tables);
3304
share->db_record_offset= 1;
3311
void Table::free_tmp_table(Session *session)
3313
memory::Root own_root= mem_root;
3314
const char *save_proc_info;
3316
save_proc_info=session->get_proc_info();
3317
session->set_proc_info("removing tmp table");
3319
// Release latches since this can take a long time
3320
plugin::StorageEngine::releaseTemporaryLatches(session);
3325
cursor->closeMarkForDelete(s->table_name.str);
3327
s->db_type()->doDropTable(*session, s->table_name.str);
3333
for (Field **ptr= field ; *ptr ; ptr++)
3337
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3338
session->set_proc_info(save_proc_info);
3342
If a HEAP table gets full, create a MyISAM table and copy all rows
3346
bool create_myisam_from_heap(Session *session, Table *table,
3347
MI_COLUMNDEF *start_recinfo,
3348
MI_COLUMNDEF **recinfo,
3349
int error, bool ignore_last_dupp_key_error)
3353
const char *save_proc_info;
3356
if (table->s->db_type() != heap_engine ||
3357
error != HA_ERR_RECORD_FILE_FULL)
3359
table->print_error(error, MYF(0));
3363
// Release latches since this can take a long time
3364
plugin::StorageEngine::releaseTemporaryLatches(session);
3368
new_table.s= &share;
3369
new_table.s->storage_engine= myisam_engine;
3370
if (!(new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
3371
return true; // End of memory
3373
save_proc_info=session->get_proc_info();
3374
session->set_proc_info("converting HEAP to MyISAM");
3376
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
3377
recinfo, session->lex->select_lex.options |
3380
if (new_table.open_tmp_table())
3382
if (table->cursor->indexes_are_disabled())
3383
new_table.cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3384
table->cursor->ha_index_or_rnd_end();
3385
table->cursor->ha_rnd_init(1);
3388
new_table.cursor->extra(HA_EXTRA_NO_ROWS);
3389
new_table.no_rows=1;
3392
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3393
new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
3396
copy all old rows from heap table to MyISAM table
3397
This is the only code that uses record[1] to read/write but this
3398
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3400
while (!table->cursor->rnd_next(new_table.record[1]))
3402
write_err= new_table.cursor->ha_write_row(new_table.record[1]);
3406
/* copy row that filled HEAP table */
3407
if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
3409
if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
3410
!ignore_last_dupp_key_error)
3414
/* remove heap table and change to use myisam table */
3415
(void) table->cursor->ha_rnd_end();
3416
(void) table->cursor->close(); // This deletes the table !
3417
delete table->cursor;
3418
table->cursor= NULL;
3419
new_table.s= table->s; // Keep old share
3423
table->cursor->change_table_ptr(table, table->s);
3424
table->use_all_columns();
3427
const char *new_proc_info=
3428
(!strcmp(save_proc_info,"Copying to tmp table") ?
3429
"Copying to tmp table on disk" : save_proc_info);
3430
session->set_proc_info(new_proc_info);
3435
table->print_error(write_err, MYF(0));
3436
(void) table->cursor->ha_rnd_end();
3437
(void) new_table.cursor->close();
3439
new_table.s->db_type()->doDropTable(*session, new_table.s->table_name.str);
3441
delete new_table.cursor;
3442
session->set_proc_info(save_proc_info);
3443
table->mem_root= new_table.mem_root;
3447
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
3449
my_bitmap_map *old= bitmap->getBitmap();
3450
bitmap->setBitmap(s->all_set.getBitmap());
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
3454
void Table::restore_column_map(my_bitmap_map *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
3456
read_set->setBitmap(old);
1436
3459
uint32_t Table::find_shortest_key(const key_map *usable_keys)