42
32
#include <drizzled/field/double.h>
43
33
#include <drizzled/unireg.h>
44
34
#include <drizzled/message/table.pb.h>
45
#include "drizzled/sql_table.h"
46
#include "drizzled/charset.h"
47
#include "drizzled/internal/m_string.h"
48
#include "plugin/myisam/myisam.h"
50
36
#include <drizzled/item/string.h>
51
37
#include <drizzled/item/int.h>
52
38
#include <drizzled/item/decimal.h>
53
39
#include <drizzled/item/float.h>
54
40
#include <drizzled/item/null.h>
55
#include <drizzled/temporal.h>
57
#include "drizzled/table/instance.h"
59
#include "drizzled/table_proto.h"
42
#include <drizzled/table_proto.h>
48
using namespace drizzled;
61
49
using namespace std;
66
extern pid_t current_pid;
67
extern plugin::StorageEngine *heap_engine;
68
extern plugin::StorageEngine *myisam_engine;
70
/* Functions defined in this cursor */
50
using namespace drizzled;
52
/* Functions defined in this file */
72
54
void open_table_error(TableShare *share, int error, int db_errno,
73
55
myf errortype, int errarg);
75
57
/*************************************************************************/
77
// @note this should all be the destructor
78
int Table::delete_table(bool free_share)
59
/* Get column name from column hash */
61
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
63
*length= (uint32_t) strlen((*buff)->field_name);
64
return (unsigned char*) (*buff)->field_name;
69
Returns pointer to '.frm' extension of the file name.
76
Checks file name part starting with the rightmost '.' character,
77
and returns it if it is equal to '.dfe'.
80
It is a good idea to get rid of this function modifying the code
81
to garantee that the functions presently calling fn_rext() always
82
get arguments in the same format: either with '.frm' or without '.frm'.
85
Pointer to the '.frm' extension. If there is no extension,
86
or extension is not '.frm', pointer at the end of file name.
89
char *fn_rext(char *name)
91
char *res= strrchr(name, '.');
92
if (res && !strcmp(res, ".dfe"))
94
return name + strlen(name);
97
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
101
if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
102
(my_strcasecmp(system_charset_info,
103
INFORMATION_SCHEMA_NAME.c_str(),
106
return TABLE_CATEGORY_INFORMATION;
109
return TABLE_CATEGORY_USER;
114
Allocate a setup TableShare structure
118
TableList Take database and table name from there
119
key Table cache key (db \0 table_name \0...)
120
key_length Length of key
123
0 Error (out of memory)
127
TableShare *alloc_table_share(TableList *table_list, char *key,
132
char *key_buff, *path_buff;
133
char path[FN_REFLEN];
134
uint32_t path_length;
136
path_length= build_table_filename(path, sizeof(path) - 1,
138
table_list->table_name, false);
139
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
140
if (multi_alloc_root(&mem_root,
141
&share, sizeof(*share),
142
&key_buff, key_length,
143
&path_buff, path_length + 1,
146
memset(share, 0, sizeof(*share));
148
share->set_table_cache_key(key_buff, key, key_length);
150
share->path.str= path_buff;
151
share->path.length= path_length;
152
strcpy(share->path.str, path);
153
share->normalized_path.str= share->path.str;
154
share->normalized_path.length= path_length;
156
share->version= refresh_version;
158
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
159
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
160
pthread_cond_init(&share->cond, NULL);
166
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
168
enum_field_types field_type;
170
switch(proto_field_type)
172
case message::Table::Field::INTEGER:
173
field_type= DRIZZLE_TYPE_LONG;
175
case message::Table::Field::DOUBLE:
176
field_type= DRIZZLE_TYPE_DOUBLE;
178
case message::Table::Field::TIMESTAMP:
179
field_type= DRIZZLE_TYPE_TIMESTAMP;
181
case message::Table::Field::BIGINT:
182
field_type= DRIZZLE_TYPE_LONGLONG;
184
case message::Table::Field::DATETIME:
185
field_type= DRIZZLE_TYPE_DATETIME;
187
case message::Table::Field::DATE:
188
field_type= DRIZZLE_TYPE_DATE;
190
case message::Table::Field::VARCHAR:
191
field_type= DRIZZLE_TYPE_VARCHAR;
193
case message::Table::Field::DECIMAL:
194
field_type= DRIZZLE_TYPE_NEWDECIMAL;
196
case message::Table::Field::ENUM:
197
field_type= DRIZZLE_TYPE_ENUM;
199
case message::Table::Field::BLOB:
200
field_type= DRIZZLE_TYPE_BLOB;
203
field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
210
static Item *default_value_item(enum_field_types field_type,
211
const CHARSET_INFO *charset,
212
bool default_null, const string *default_value,
213
const string *default_bin_value)
215
Item *default_item= NULL;
220
return new Item_null();
225
case DRIZZLE_TYPE_TINY:
226
case DRIZZLE_TYPE_LONG:
227
case DRIZZLE_TYPE_LONGLONG:
228
default_item= new Item_int(default_value->c_str(),
229
(int64_t) my_strtoll10(default_value->c_str(),
232
default_value->length());
234
case DRIZZLE_TYPE_DOUBLE:
235
default_item= new Item_float(default_value->c_str(),
236
default_value->length());
238
case DRIZZLE_TYPE_NULL:
240
case DRIZZLE_TYPE_TIMESTAMP:
241
case DRIZZLE_TYPE_DATETIME:
242
case DRIZZLE_TYPE_DATE:
243
if (default_value->compare("NOW()") == 0)
245
case DRIZZLE_TYPE_ENUM:
246
default_item= new Item_string(default_value->c_str(),
247
default_value->length(),
248
system_charset_info);
250
case DRIZZLE_TYPE_VARCHAR:
251
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
252
if (charset==&my_charset_bin)
254
default_item= new Item_string(default_bin_value->c_str(),
255
default_bin_value->length(),
260
default_item= new Item_string(default_value->c_str(),
261
default_value->length(),
262
system_charset_info);
265
case DRIZZLE_TYPE_NEWDECIMAL:
266
default_item= new Item_decimal(default_value->c_str(),
267
default_value->length(),
268
system_charset_info);
275
int parse_table_proto(Session *session,
276
message::Table &table,
280
handler *handler_file= NULL;
282
share->setTableProto(new(nothrow) message::Table(table));
284
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
286
message::Table::TableOptions table_options;
288
if (table.has_options())
289
table_options= table.options();
291
uint32_t db_create_options= 0;
293
if (table_options.has_pack_keys())
295
if (table_options.pack_keys())
296
db_create_options|= HA_OPTION_PACK_KEYS;
298
db_create_options|= HA_OPTION_NO_PACK_KEYS;
301
if (table_options.pack_record())
302
db_create_options|= HA_OPTION_PACK_RECORD;
304
/* db_create_options was stored as 2 bytes in FRM
305
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
307
share->db_create_options= (db_create_options & 0x0000FFFF);
308
share->db_options_in_use= share->db_create_options;
310
share->row_type= table_options.has_row_type() ?
311
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
313
share->block_size= table_options.has_block_size() ?
314
table_options.block_size() : 0;
316
share->table_charset= get_charset(table_options.has_collation_id()?
317
table_options.collation_id() : 0);
319
if (!share->table_charset)
321
/* unknown charset in head[38] or pre-3.23 frm */
322
if (use_mb(default_charset_info))
324
/* Warn that we may be changing the size of character columns */
325
errmsg_printf(ERRMSG_LVL_WARN,
326
_("'%s' had no or invalid character set, "
327
"and default character set is multi-byte, "
328
"so character column sizes may have changed"),
331
share->table_charset= default_charset_info;
334
share->db_record_offset= 1;
336
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
338
share->db_low_byte_first= true;
340
share->keys= table.indexes_size();
343
for (int indx= 0; indx < table.indexes_size(); indx++)
344
share->key_parts+= table.indexes(indx).index_part_size();
346
share->key_info= (KEY*) alloc_root(&share->mem_root,
347
table.indexes_size() * sizeof(KEY)
348
+share->key_parts*sizeof(KEY_PART_INFO));
350
KEY_PART_INFO *key_part;
352
key_part= reinterpret_cast<KEY_PART_INFO*>
353
(share->key_info+table.indexes_size());
356
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
357
sizeof(ulong*)*share->key_parts);
359
share->keynames.count= table.indexes_size();
360
share->keynames.name= NULL;
361
share->keynames.type_names= (const char**)
362
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
364
share->keynames.type_lengths= (unsigned int*)
365
alloc_root(&share->mem_root,
366
sizeof(unsigned int) * (table.indexes_size()+1));
368
share->keynames.type_names[share->keynames.count]= NULL;
369
share->keynames.type_lengths[share->keynames.count]= 0;
371
KEY* keyinfo= share->key_info;
372
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
374
message::Table::Index indx= table.indexes(keynr);
379
if (indx.is_unique())
380
keyinfo->flags|= HA_NOSAME;
382
if (indx.has_options())
384
message::Table::Index::IndexOptions indx_options= indx.options();
385
if (indx_options.pack_key())
386
keyinfo->flags|= HA_PACK_KEY;
388
if (indx_options.var_length_key())
389
keyinfo->flags|= HA_VAR_LENGTH_PART;
391
if (indx_options.null_part_key())
392
keyinfo->flags|= HA_NULL_PART_KEY;
394
if (indx_options.binary_pack_key())
395
keyinfo->flags|= HA_BINARY_PACK_KEY;
397
if (indx_options.has_partial_segments())
398
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
400
if (indx_options.auto_generated_key())
401
keyinfo->flags|= HA_GENERATED_KEY;
403
if (indx_options.has_key_block_size())
405
keyinfo->flags|= HA_USES_BLOCK_SIZE;
406
keyinfo->block_size= indx_options.key_block_size();
410
keyinfo->block_size= 0;
416
case message::Table::Index::UNKNOWN_INDEX:
417
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
419
case message::Table::Index::BTREE:
420
keyinfo->algorithm= HA_KEY_ALG_BTREE;
422
case message::Table::Index::RTREE:
423
keyinfo->algorithm= HA_KEY_ALG_RTREE;
425
case message::Table::Index::HASH:
426
keyinfo->algorithm= HA_KEY_ALG_HASH;
428
case message::Table::Index::FULLTEXT:
429
keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
432
/* TODO: suitable warning ? */
433
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
437
keyinfo->key_length= indx.key_length();
439
keyinfo->key_parts= indx.index_part_size();
441
keyinfo->key_part= key_part;
442
keyinfo->rec_per_key= rec_per_key;
444
for (unsigned int partnr= 0;
445
partnr < keyinfo->key_parts;
446
partnr++, key_part++)
448
message::Table::Index::IndexPart part;
449
part= indx.index_part(partnr);
453
key_part->field= NULL;
454
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
455
key_part->null_bit= 0;
456
/* key_part->null_offset is only set if null_bit (see later) */
457
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
458
/* key_part->type ???? */
459
key_part->key_part_flag= 0;
460
if (part.has_in_reverse_order())
461
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
463
key_part->length= part.compare_length();
465
key_part->store_length= key_part->length;
467
/* key_part->offset is set later */
468
key_part->key_type= part.key_type();
471
if (! indx.has_comment())
473
keyinfo->comment.length= 0;
474
keyinfo->comment.str= NULL;
478
keyinfo->flags|= HA_USES_COMMENT;
479
keyinfo->comment.length= indx.comment().length();
480
keyinfo->comment.str= strmake_root(&share->mem_root,
481
indx.comment().c_str(),
482
keyinfo->comment.length);
485
keyinfo->name= strmake_root(&share->mem_root,
487
indx.name().length());
489
share->keynames.type_names[keynr]= keyinfo->name;
490
share->keynames.type_lengths[keynr]= indx.name().length();
493
share->keys_for_keyread.reset();
494
set_prefix(share->keys_in_use, share->keys);
496
share->key_block_size= table_options.has_key_block_size() ?
497
table_options.key_block_size() : 0;
499
share->fields= table.field_size();
501
share->field= (Field**) alloc_root(&share->mem_root,
502
((share->fields+1) * sizeof(Field*)));
503
share->field[share->fields]= NULL;
505
uint32_t null_fields= 0;
508
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
509
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
511
assert(field_offsets && field_pack_length); // TODO: fixme
513
uint32_t interval_count= 0;
514
uint32_t interval_parts= 0;
516
uint32_t stored_columns_reclength= 0;
518
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
520
message::Table::Field pfield= table.field(fieldnr);
521
if (pfield.has_constraints() && pfield.constraints().is_nullable())
524
enum_field_types drizzle_field_type=
525
proto_field_type_to_drizzle_type(pfield.type());
527
field_offsets[fieldnr]= stored_columns_reclength;
529
/* the below switch is very similar to
530
CreateField::create_length_to_internal_length in field.cc
531
(which should one day be replace by just this code)
533
switch(drizzle_field_type)
535
case DRIZZLE_TYPE_BLOB:
536
case DRIZZLE_TYPE_VARCHAR:
538
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
540
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
541
field_options.collation_id() : 0);
544
cs= default_charset_info;
546
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
547
field_options.length() * cs->mbmaxlen);
550
case DRIZZLE_TYPE_ENUM:
552
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
554
field_pack_length[fieldnr]=
555
get_enum_pack_length(field_options.field_value_size());
558
interval_parts+= field_options.field_value_size();
561
case DRIZZLE_TYPE_NEWDECIMAL:
563
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
565
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
569
/* Zero is okay here as length is fixed for other types. */
570
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
573
share->reclength+= field_pack_length[fieldnr];
574
stored_columns_reclength+= field_pack_length[fieldnr];
577
/* data_offset added to stored_rec_length later */
578
share->stored_rec_length= stored_columns_reclength;
580
share->null_fields= null_fields;
582
ulong null_bits= null_fields;
583
if (! table_options.pack_record())
585
ulong data_offset= (null_bits + 7)/8;
588
share->reclength+= data_offset;
589
share->stored_rec_length+= data_offset;
591
ulong rec_buff_length;
593
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
594
share->rec_buff_length= rec_buff_length;
596
unsigned char* record= NULL;
598
if (! (record= (unsigned char *) alloc_root(&share->mem_root,
602
memset(record, 0, rec_buff_length);
606
if (! table_options.pack_record())
608
null_count++; // one bit for delete mark.
612
share->default_values= record;
616
share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
617
interval_count*sizeof(TYPELIB));
620
share->intervals= NULL;
622
share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
623
(share->fields + 1) * sizeof(char*));
625
share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
626
(share->fields + 1) * sizeof(unsigned int));
628
share->fieldnames.type_names[share->fields]= NULL;
629
share->fieldnames.type_lengths[share->fields]= 0;
630
share->fieldnames.count= share->fields;
633
/* Now fix the TYPELIBs for the intervals (enum values)
637
uint32_t interval_nr= 0;
639
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
641
message::Table::Field pfield= table.field(fieldnr);
644
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
645
pfield.name().c_str(),
646
pfield.name().length());
648
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
651
if (pfield.type() != message::Table::Field::ENUM)
654
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
656
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
657
field_options.collation_id() : 0);
660
charset= default_charset_info;
662
TYPELIB *t= &(share->intervals[interval_nr]);
664
t->type_names= (const char**)alloc_root(&share->mem_root,
665
(field_options.field_value_size() + 1) * sizeof(char*));
667
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
668
(field_options.field_value_size() + 1) * sizeof(unsigned int));
670
t->type_names[field_options.field_value_size()]= NULL;
671
t->type_lengths[field_options.field_value_size()]= 0;
673
t->count= field_options.field_value_size();
676
for (int n= 0; n < field_options.field_value_size(); n++)
678
t->type_names[n]= strmake_root(&share->mem_root,
679
field_options.field_value(n).c_str(),
680
field_options.field_value(n).length());
683
* Go ask the charset what the length is as for "" length=1
684
* and there's stripping spaces or some other crack going on.
687
lengthsp= charset->cset->lengthsp(charset,
689
field_options.field_value(n).length());
690
t->type_lengths[n]= lengthsp;
696
/* and read the fields */
699
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
702
use_hash= ! hash_init(&share->name_hash,
707
(hash_get_key) get_field_name,
711
unsigned char* null_pos= record;;
712
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
714
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
716
message::Table::Field pfield= table.field(fieldnr);
718
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
720
switch (pfield.format())
722
case message::Table::Field::DefaultFormat:
723
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
725
case message::Table::Field::FixedFormat:
726
column_format= COLUMN_FORMAT_TYPE_FIXED;
728
case message::Table::Field::DynamicFormat:
729
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
735
Field::utype unireg_type= Field::NONE;
737
if (pfield.has_numeric_options() &&
738
pfield.numeric_options().is_autoincrement())
740
unireg_type= Field::NEXT_NUMBER;
743
if (pfield.has_options() &&
744
pfield.options().has_default_value() &&
745
pfield.options().default_value().compare("NOW()") == 0)
747
if (pfield.options().has_update_value() &&
748
pfield.options().update_value().compare("NOW()") == 0)
750
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
752
else if (! pfield.options().has_update_value())
754
unireg_type= Field::TIMESTAMP_DN_FIELD;
757
assert(1); // Invalid update value.
759
else if (pfield.has_options() &&
760
pfield.options().has_update_value() &&
761
pfield.options().update_value().compare("NOW()") == 0)
763
unireg_type= Field::TIMESTAMP_UN_FIELD;
767
if (!pfield.has_comment())
769
comment.str= (char*)"";
774
size_t len= pfield.comment().length();
775
const char* str= pfield.comment().c_str();
777
comment.str= strmake_root(&share->mem_root, str, len);
781
enum_field_types field_type;
783
field_type= proto_field_type_to_drizzle_type(pfield.type());
785
const CHARSET_INFO *charset= &my_charset_bin;
787
if (field_type == DRIZZLE_TYPE_BLOB ||
788
field_type == DRIZZLE_TYPE_VARCHAR)
790
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
792
charset= get_charset(field_options.has_collation_id() ?
793
field_options.collation_id() : 0);
796
charset= default_charset_info;
799
if (field_type == DRIZZLE_TYPE_ENUM)
801
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
803
charset= get_charset(field_options.has_collation_id()?
804
field_options.collation_id() : 0);
807
charset= default_charset_info;
811
if (field_type == DRIZZLE_TYPE_NEWDECIMAL
812
|| field_type == DRIZZLE_TYPE_DOUBLE)
814
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
816
if (! pfield.has_numeric_options() || ! fo.has_scale())
819
We don't write the default to table proto so
820
if no decimals specified for DOUBLE, we use the default.
822
decimals= NOT_FIXED_DEC;
826
if (fo.scale() > DECIMAL_MAX_SCALE)
831
decimals= static_cast<uint8_t>(fo.scale());
835
Item *default_value= NULL;
837
if (pfield.options().has_default_value() ||
838
pfield.options().has_default_null() ||
839
pfield.options().has_default_bin_value())
841
default_value= default_value_item(field_type,
843
pfield.options().default_null(),
844
&pfield.options().default_value(),
845
&pfield.options().default_bin_value());
849
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
850
memset(&temp_table, 0, sizeof(temp_table));
852
temp_table.in_use= session;
853
temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
854
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
856
Field* f= make_field(share,
858
record + field_offsets[fieldnr] + data_offset,
859
pfield.options().length(),
860
pfield.has_constraints() && pfield.constraints().is_nullable() ? true : false,
866
(Field::utype) MTYP_TYPENR(unireg_type),
867
((field_type == DRIZZLE_TYPE_ENUM) ?
868
share->intervals + (interval_nr++)
870
share->fieldnames.type_names[fieldnr]);
872
share->field[fieldnr]= f;
874
f->init(&temp_table); /* blob default values need table obj */
876
if (! (f->flags & NOT_NULL_FLAG))
878
*f->null_ptr|= f->null_bit;
879
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
886
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
887
session->count_cuted_fields= CHECK_FIELD_WARN;
888
int res= default_value->save_in_field(f, 1);
889
session->count_cuted_fields= old_count_cuted_fields;
890
if (res != 0 && res != 3) /* @TODO Huh? */
892
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
897
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
898
(f->flags & NOT_NULL_FLAG))
901
f->store((int64_t) 1, true);
906
/* hack to undo f->init() */
910
f->field_index= fieldnr;
912
if (! default_value &&
913
! (f->unireg_check==Field::NEXT_NUMBER) &&
914
(f->flags & NOT_NULL_FLAG) &&
915
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
917
f->flags|= NO_DEFAULT_VALUE_FLAG;
920
if (f->unireg_check == Field::NEXT_NUMBER)
921
share->found_next_number_field= &(share->field[fieldnr]);
923
if (share->timestamp_field == f)
924
share->timestamp_field_offset= fieldnr;
926
if (use_hash) /* supposedly this never fails... but comments lie */
927
(void) my_hash_insert(&share->name_hash,
928
(unsigned char*)&(share->field[fieldnr]));
932
keyinfo= share->key_info;
933
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
935
key_part= keyinfo->key_part;
937
for (unsigned int partnr= 0;
938
partnr < keyinfo->key_parts;
939
partnr++, key_part++)
942
* Fix up key_part->offset by adding data_offset.
943
* We really should compute offset as well.
944
* But at least this way we are a little better.
946
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
951
We need to set the unused bits to 1. If the number of bits is a multiple
952
of 8 there are no unused bits.
956
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
958
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
960
share->last_null_bit_pos= null_bit_pos;
963
free(field_pack_length);
965
if (! (handler_file= get_new_handler(share,
971
if (share->key_parts)
973
uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
974
&share->keynames, 3) - 1); /* @TODO Huh? */
976
int64_t ha_option= handler_file->ha_table_flags();
978
keyinfo= share->key_info;
979
key_part= keyinfo->key_part;
981
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
983
uint32_t usable_parts= 0;
985
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
988
If the UNIQUE key doesn't have NULL columns and is not a part key
989
declare this as a primary key.
992
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
994
uint32_t fieldnr= key_part[i].fieldnr;
996
share->field[fieldnr-1]->null_ptr ||
997
share->field[fieldnr-1]->key_length() != key_part[i].length)
999
primary_key= MAX_KEY; // Can't be used
1005
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1008
if (! key_part->fieldnr)
1010
abort(); // goto err;
1012
field= key_part->field= share->field[key_part->fieldnr-1];
1013
key_part->type= field->key_type();
1014
if (field->null_ptr)
1016
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1017
share->default_values);
1018
key_part->null_bit= field->null_bit;
1019
key_part->store_length+=HA_KEY_NULL_LENGTH;
1020
keyinfo->flags|=HA_NULL_PART_KEY;
1021
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1022
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1024
if (field->type() == DRIZZLE_TYPE_BLOB ||
1025
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1027
if (field->type() == DRIZZLE_TYPE_BLOB)
1028
key_part->key_part_flag|= HA_BLOB_PART;
1030
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1031
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1032
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1033
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1035
if (i == 0 && key != primary_key)
1036
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1037
(keyinfo->key_parts == 1)) ?
1038
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1040
field->key_start.set(key);
1041
if (field->key_length() == key_part->length &&
1042
!(field->flags & BLOB_FLAG))
1044
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1046
share->keys_for_keyread.set(key);
1047
field->part_of_key.set(key);
1048
field->part_of_key_not_clustered.set(key);
1050
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1051
field->part_of_sortkey.set(key);
1053
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1055
usable_parts++; // For FILESORT
1056
field->flags|= PART_KEY_FLAG;
1057
if (key == primary_key)
1059
field->flags|= PRI_KEY_FLAG;
1061
If this field is part of the primary key and all keys contains
1062
the primary key, then we can use any key to find this column
1064
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1066
field->part_of_key= share->keys_in_use;
1067
if (field->part_of_sortkey.test(key))
1068
field->part_of_sortkey= share->keys_in_use;
1071
if (field->key_length() != key_part->length)
1073
key_part->key_part_flag|= HA_PART_KEY_SEG;
1076
keyinfo->usable_key_parts= usable_parts; // Filesort
1078
set_if_bigger(share->max_key_length,keyinfo->key_length+
1079
keyinfo->key_parts);
1080
share->total_key_length+= keyinfo->key_length;
1082
MERGE tables do not have unique indexes. But every key could be
1083
an unique index on the underlying MyISAM table. (Bug #10400)
1085
if ((keyinfo->flags & HA_NOSAME) ||
1086
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1087
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1089
if (primary_key < MAX_KEY &&
1090
(share->keys_in_use.test(primary_key)))
1092
share->primary_key= primary_key;
1094
If we are using an integer as the primary key then allow the user to
1095
refer to it as '_rowid'
1097
if (share->key_info[primary_key].key_parts == 1)
1099
Field *field= share->key_info[primary_key].key_part[0].field;
1100
if (field && field->result_type() == INT_RESULT)
1102
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1103
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1109
share->primary_key = MAX_KEY; // we do not have a primary key
1112
share->primary_key= MAX_KEY;
1114
if (share->found_next_number_field)
1116
Field *reg_field= *share->found_next_number_field;
1117
if ((int) (share->next_number_index= (uint32_t)
1118
find_ref_key(share->key_info, share->keys,
1119
share->default_values, reg_field,
1120
&share->next_number_key_offset,
1121
&share->next_number_keypart)) < 0)
1123
/* Wrong field definition */
1128
reg_field->flags |= AUTO_INCREMENT_FLAG;
1131
if (share->blob_fields)
1136
/* Store offsets to blob fields to find them fast */
1137
if (!(share->blob_field= save=
1138
(uint*) alloc_root(&share->mem_root,
1139
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1141
for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1143
if ((*ptr)->flags & BLOB_FLAG)
1148
share->db_low_byte_first= handler_file->low_byte_first();
1149
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1151
my_bitmap_map *bitmaps;
1153
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1154
share->column_bitmap_size)))
1156
share->all_set.init(bitmaps, share->fields);
1157
share->all_set.setAll();
1160
delete handler_file;
1164
share->error= error;
1165
share->open_errno= my_errno;
1167
hash_free(&share->name_hash);
1169
delete handler_file;
1170
share->open_table_error(error, share->open_errno, 0);
1176
Read table definition from a binary / text based .frm file
1180
session Thread handler
1181
share Fill this with table definition
1184
This function is called when the table definition is not cached in
1186
The data is returned in 'share', which is alloced by
1187
alloc_table_share().. The code assumes that share is initialized.
1191
1 Error (see open_table_error)
1192
2 Error (see open_table_error)
1193
3 Wrong data in .frm file
1194
4 Error (see open_table_error)
1195
5 Error (see open_table_error: charset unavailable)
1196
6 Unknown .frm version
1199
int open_table_def(Session *session, TableShare *share)
1207
message::Table table;
1209
error= plugin::StorageEngine::getTableProto(share->normalized_path.str,
1212
if (error != EEXIST)
1221
if (!table.IsInitialized())
1229
error= parse_table_proto(session, table, share);
1231
share->table_category= get_table_category(& share->db);
1234
session->status_var.opened_shares++;
1237
if (error && !error_given)
1239
share->error= error;
1240
share->open_table_error(error, (share->open_errno= my_errno), 0);
1248
Open a table based on a TableShare
1251
open_table_from_share()
1252
session Thread handler
1253
share Table definition
1254
alias Alias for table
1255
db_stat open flags (for example HA_OPEN_KEYFILE|
1256
HA_OPEN_RNDFILE..) can be 0 (example in
1258
prgflag READ_ALL etc..
1259
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1260
outparam result table
1261
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1262
if OTM_CREATE some errors are ignore
1263
if OTM_ALTER HA_OPEN is not called
1267
1 Error (see open_table_error)
1268
2 Error (see open_table_error)
1269
3 Wrong data in .frm file
1270
4 Error (see open_table_error)
1271
5 Error (see open_table_error: charset unavailable)
1272
7 Table definition has changed in engine
1275
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1276
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1277
Table *outparam, open_table_mode open_mode)
1280
uint32_t records, i, bitmap_size;
1281
bool error_reported= false;
1282
unsigned char *record, *bitmaps;
1285
/* Parsing of partitioning information from .frm needs session->lex set up. */
1286
assert(session->lex->is_lex_started);
1289
outparam->resetTable(session, share, db_stat);
1292
if (!(outparam->alias= strdup(alias)))
1295
/* Allocate handler */
1296
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1298
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1309
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1311
if (prgflag & (READ_ALL+EXTRA_RECORD))
1314
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1315
share->rec_buff_length * records)))
1320
/* We are probably in hard repair, and the buffers should not be used */
1321
outparam->record[0]= outparam->record[1]= share->default_values;
1325
outparam->record[0]= record;
1327
outparam->record[1]= record+ share->rec_buff_length;
1329
outparam->record[1]= outparam->record[0]; // Safety
1334
We need this because when we read var-length rows, we are not updating
1335
bytes after end of varchar
1339
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1340
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1342
memcpy(outparam->record[1], share->default_values,
1343
share->rec_buff_length);
1347
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1348
(uint32_t) ((share->fields+1)*
1352
outparam->field= field_ptr;
1354
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1356
outparam->null_flags= (unsigned char*) record+1;
1358
/* Setup copy of fields from share, but use the right alias and record */
1359
for (i= 0 ; i < share->fields; i++, field_ptr++)
1361
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1364
(*field_ptr)= 0; // End marker
1366
if (share->found_next_number_field)
1367
outparam->found_next_number_field=
1368
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1369
if (share->timestamp_field)
1370
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1373
/* Fix key->name and key_part->field */
1374
if (share->key_parts)
1376
KEY *key_info, *key_info_end;
1377
KEY_PART_INFO *key_part;
1379
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1380
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1382
outparam->key_info= key_info;
1383
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1385
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1386
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1389
for (key_info_end= key_info + share->keys ;
1390
key_info < key_info_end ;
1393
KEY_PART_INFO *key_part_end;
1395
key_info->table= outparam;
1396
key_info->key_part= key_part;
1398
for (key_part_end= key_part+ key_info->key_parts ;
1399
key_part < key_part_end ;
1402
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1404
if (field->key_length() != key_part->length &&
1405
!(field->flags & BLOB_FLAG))
1408
We are using only a prefix of the column as a key:
1409
Create a new field for the key part that matches the index
1411
field= key_part->field=field->new_field(&outparam->mem_root,
1413
field->field_length= key_part->length;
1419
/* Allocate bitmaps */
1421
bitmap_size= share->column_bitmap_size;
1422
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1424
outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1425
outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1426
outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1427
outparam->default_column_bitmaps();
1429
/* The table struct is now initialized; Open the table */
1431
if (db_stat && open_mode != OTM_ALTER)
1434
if ((ha_err= (outparam->file->
1435
ha_open(outparam, share->normalized_path.str,
1436
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1437
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1438
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1439
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1440
HA_OPEN_ABORT_IF_LOCKED :
1441
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1443
/* Set a flag if the table is crashed and it can be auto. repaired */
1444
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1445
outparam->file->auto_repair() &&
1446
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1450
case HA_ERR_NO_SUCH_TABLE:
1452
The table did not exists in storage engine, use same error message
1453
as if the .frm file didn't exist
1460
Too many files opened, use same error message as if the .frm
1467
outparam->file->print_error(ha_err, MYF(0));
1468
error_reported= true;
1469
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1477
#if defined(HAVE_purify)
1478
memset(bitmaps, 0, bitmap_size*3);
1481
session->status_var.opened_tables++;
1486
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1487
share->open_table_error(error, my_errno, 0);
1488
delete outparam->file;
1489
outparam->file= 0; // For easier error checking
1490
outparam->db_stat= 0;
1491
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1492
free((char*) outparam->alias);
1497
Free information allocated by openfrm
1501
table Table object to free
1502
free_share Is 1 if we also want to free table_share
1505
int Table::closefrm(bool free_share)
83
error= cursor->close();
1510
error= file->close();
1511
free((char*) alias);
87
1515
for (Field **ptr=field ; *ptr ; ptr++)
94
cursor= 0; /* For easier errorchecking */
1520
file= 0; /* For easier errorchecking */
1523
if (s->tmp_table == NO_TMP_TABLE)
1524
TableShare::release(s);
1526
s->free_table_share();
1528
free_root(&mem_root, MYF(0));
106
mem_root.free_root(MYF(0));
110
void Table::resetTable(Session *session,
112
uint32_t db_stat_arg)
125
db_stat= db_stat_arg;
128
record[0]= (unsigned char *) NULL;
129
record[1]= (unsigned char *) NULL;
131
insert_values.clear();
133
next_number_field= NULL;
134
found_next_number_field= NULL;
135
timestamp_field= NULL;
137
pos_in_table_list= NULL;
147
derived_select_number= 0;
148
current_lock= F_UNLCK;
162
open_placeholder= false;
163
locked_by_name= false;
166
auto_increment_field_not_null= false;
167
alias_name_used= false;
170
quick_condition_rows= 0;
172
timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
177
covering_keys.reset();
182
keys_in_use_for_query.reset();
183
keys_in_use_for_group_by.reset();
184
keys_in_use_for_order_by.reset();
186
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
187
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
189
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
190
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
192
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
197
1534
/* Deallocate temporary blob storage */
1398
2932
session->mem_root= mem_root_save;
2933
table->free_tmp_table(session);
1404
2937
/****************************************************************************/
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;
2940
Create a reduced Table object with properly set up Field list from a
2941
list of field definitions.
2943
The created table doesn't have a table handler associated with
2944
it, has no keys, no group/distinct, no copy_funcs array.
2945
The sole purpose of this Table object is to use the power of Field
2946
class to read/write data to/from table->record[0]. Then one can store
2947
the record in any container (RB tree, hash, etc).
2948
The table is created in Session mem_root, so are the table's fields.
2949
Consequently, if you don't BLOB fields, you don't need to free it.
2951
@param session connection handle
2952
@param field_list list of column definitions
2955
0 if out of memory, Table object in case of success
2958
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
2960
uint32_t field_count= field_list.elements;
2961
uint32_t blob_count= 0;
2963
CreateField *cdef; /* column definition */
2964
uint32_t record_length= 0;
2965
uint32_t null_count= 0; /* number of columns which may be null */
2966
uint32_t null_pack_length; /* NULL representation array length */
2967
uint32_t *blob_field;
2968
unsigned char *bitmaps;
2972
if (!multi_alloc_root(session->mem_root,
2973
&table, sizeof(*table),
2974
&share, sizeof(*share),
2975
&field, (field_count + 1) * sizeof(Field*),
2976
&blob_field, (field_count+1) *sizeof(uint32_t),
2977
&bitmaps, bitmap_buffer_size(field_count)*2,
2981
memset(table, 0, sizeof(*table));
2982
memset(share, 0, sizeof(*share));
2983
table->field= field;
2985
share->blob_field= blob_field;
2986
share->fields= field_count;
2987
share->blob_ptr_size= portable_sizeof_char_ptr;
2988
table->setup_tmp_table_column_bitmaps(bitmaps);
2990
/* Create all fields and calculate the total length of record */
2991
List_iterator_fast<CreateField> it(field_list);
2992
while ((cdef= it++))
2994
*field= make_field(share,
2998
(cdef->flags & NOT_NULL_FLAG) ? false : true,
2999
(unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
3000
(cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3009
(*field)->init(table);
3010
record_length+= (*field)->pack_length();
3011
if (! ((*field)->flags & NOT_NULL_FLAG))
3014
if ((*field)->flags & BLOB_FLAG)
3015
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
3019
*field= NULL; /* mark the end of the list */
3020
share->blob_field[blob_count]= 0; /* mark the end of the list */
3021
share->blob_fields= blob_count;
3023
null_pack_length= (null_count + 7)/8;
3024
share->reclength= record_length + null_pack_length;
3025
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3026
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
3027
if (!table->record[0])
3030
if (null_pack_length)
3032
table->null_flags= (unsigned char*) table->record[0];
3033
share->null_fields= null_count;
3034
share->null_bytes= null_pack_length;
3037
table->in_use= session; /* field->reset() may access table->in_use */
3039
/* Set up field pointers */
3040
unsigned char *null_pos= table->record[0];
3041
unsigned char *field_pos= null_pos + share->null_bytes;
3042
uint32_t null_bit= 1;
3044
for (field= table->field; *field; ++field)
3046
Field *cur_field= *field;
3047
if ((cur_field->flags & NOT_NULL_FLAG))
3048
cur_field->move_field(field_pos);
3051
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
3053
if (null_bit == (1 << 8))
3061
field_pos+= cur_field->pack_length();
3066
for (field= table->field; *field; ++field)
3067
delete *field; /* just invokes field destructor */
3071
bool Table::open_tmp_table()
3074
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3075
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3077
file->print_error(error,MYF(0));
3081
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
3087
Create MyISAM temporary table
3090
create_myisam_tmp_table()
3091
keyinfo Description of the index (there is always one index)
3092
start_recinfo MyISAM's column descriptions
3093
recinfo INOUT End of MyISAM's column descriptions
3097
Create a MyISAM temporary table according to passed description. The is
3098
assumed to have one unique index or constraint.
3100
The passed array or MI_COLUMNDEF structures must have this form:
3102
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
3103
when there are many nullable columns)
3105
3. One free MI_COLUMNDEF element (*recinfo points here)
3107
This function may use the free element to create hash column for unique
3115
bool Table::create_myisam_tmp_table(KEY *keyinfo,
3116
MI_COLUMNDEF *start_recinfo,
3117
MI_COLUMNDEF **recinfo,
3122
MI_UNIQUEDEF uniquedef;
3123
TableShare *share= s;
3126
{ // Get keys for ni_create
3127
bool using_unique_constraint= 0;
3128
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3129
sizeof(*seg) * keyinfo->key_parts);
3133
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3134
if (keyinfo->key_length >= file->max_key_length() ||
3135
keyinfo->key_parts > file->max_key_parts() ||
3138
/* Can't create a key; Make a unique constraint instead of a key */
3141
using_unique_constraint=1;
3142
memset(&uniquedef, 0, sizeof(uniquedef));
3143
uniquedef.keysegs=keyinfo->key_parts;
3145
uniquedef.null_are_equal=1;
3147
/* Create extra column for hash value */
3148
memset(*recinfo, 0, sizeof(**recinfo));
3149
(*recinfo)->type= FIELD_CHECK;
3150
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
3152
share->reclength+=MI_UNIQUE_HASH_LENGTH;
3156
/* Create an unique key */
3157
memset(&keydef, 0, sizeof(keydef));
3158
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
3159
keydef.keysegs= keyinfo->key_parts;
3162
for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
3164
Field *key_field=keyinfo->key_part[i].field;
3166
seg->language= key_field->charset()->number;
3167
seg->length= keyinfo->key_part[i].length;
3168
seg->start= keyinfo->key_part[i].offset;
3169
if (key_field->flags & BLOB_FLAG)
3171
seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
3172
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3173
seg->bit_start= (uint8_t)(key_field->pack_length()
3174
- share->blob_ptr_size);
3175
seg->flag= HA_BLOB_PART;
3176
seg->length= 0; // Whole blob in unique constraint
3180
seg->type= keyinfo->key_part[i].type;
3182
if (!(key_field->flags & NOT_NULL_FLAG))
3184
seg->null_bit= key_field->null_bit;
3185
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
3187
We are using a GROUP BY on something that contains NULL
3188
In this case we have to tell MyISAM that two NULL should
3189
on INSERT be regarded at the same value
3191
if (!using_unique_constraint)
3192
keydef.flag|= HA_NULL_ARE_EQUAL;
3196
MI_CREATE_INFO create_info;
3197
memset(&create_info, 0, sizeof(create_info));
3199
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3201
create_info.data_file_length= ~(uint64_t) 0;
3203
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3204
(uint32_t) (*recinfo-start_recinfo),
3206
share->uniques, &uniquedef,
3208
HA_CREATE_TMP_TABLE)))
3210
file->print_error(error,MYF(0));
3214
status_var_increment(in_use->status_var.created_tmp_disk_tables);
3215
share->db_record_offset= 1;
3222
void Table::free_tmp_table(Session *session)
3224
MEM_ROOT own_root= mem_root;
3225
const char *save_proc_info;
3227
save_proc_info=session->get_proc_info();
3228
session->set_proc_info("removing tmp table");
3230
// Release latches since this can take a long time
3231
plugin::StorageEngine::releaseTemporaryLatches(session);
3236
file->closeMarkForDelete(s->table_name.str);
3238
s->db_type()->doDeleteTable(session, s->table_name.str);
3244
for (Field **ptr= field ; *ptr ; ptr++)
3248
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3249
session->set_proc_info(save_proc_info);
3253
If a HEAP table gets full, create a MyISAM table and copy all rows
3257
bool create_myisam_from_heap(Session *session, Table *table,
3258
MI_COLUMNDEF *start_recinfo,
3259
MI_COLUMNDEF **recinfo,
3260
int error, bool ignore_last_dupp_key_error)
3264
const char *save_proc_info;
3267
if (table->s->db_type() != heap_engine ||
3268
error != HA_ERR_RECORD_FILE_FULL)
3270
table->file->print_error(error,MYF(0));
3274
// Release latches since this can take a long time
3275
plugin::StorageEngine::releaseTemporaryLatches(session);
3279
new_table.s= &share;
3280
new_table.s->storage_engine= myisam_engine;
3281
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
3282
new_table.s->db_type())))
3283
return true; // End of memory
3285
save_proc_info=session->get_proc_info();
3286
session->set_proc_info("converting HEAP to MyISAM");
3288
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
3289
recinfo, session->lex->select_lex.options |
3292
if (new_table.open_tmp_table())
3294
if (table->file->indexes_are_disabled())
3295
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3296
table->file->ha_index_or_rnd_end();
3297
table->file->ha_rnd_init(1);
3300
new_table.file->extra(HA_EXTRA_NO_ROWS);
3301
new_table.no_rows=1;
3304
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3305
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3308
copy all old rows from heap table to MyISAM table
3309
This is the only code that uses record[1] to read/write but this
3310
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3312
while (!table->file->rnd_next(new_table.record[1]))
3314
write_err= new_table.file->ha_write_row(new_table.record[1]);
3318
/* copy row that filled HEAP table */
3319
if ((write_err=new_table.file->ha_write_row(table->record[0])))
3321
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3322
!ignore_last_dupp_key_error)
3326
/* remove heap table and change to use myisam table */
3327
(void) table->file->ha_rnd_end();
3328
(void) table->file->close(); // This deletes the table !
3331
new_table.s= table->s; // Keep old share
3335
table->file->change_table_ptr(table, table->s);
3336
table->use_all_columns();
3339
const char *new_proc_info=
3340
(!strcmp(save_proc_info,"Copying to tmp table") ?
3341
"Copying to tmp table on disk" : save_proc_info);
3342
session->set_proc_info(new_proc_info);
3347
table->file->print_error(write_err, MYF(0));
3348
(void) table->file->ha_rnd_end();
3349
(void) new_table.file->close();
3351
new_table.s->db_type()->doDeleteTable(session, new_table.s->table_name.str);
3353
delete new_table.file;
3354
session->set_proc_info(save_proc_info);
3355
table->mem_root= new_table.mem_root;
3359
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
3361
my_bitmap_map *old= bitmap->getBitmap();
3362
bitmap->setBitmap(s->all_set.getBitmap());
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
3366
void Table::restore_column_map(my_bitmap_map *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
3368
read_set->setBitmap(old);
1436
3371
uint32_t Table::find_shortest_key(const key_map *usable_keys)