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"
49
#include "drizzled/plugin/storage_engine.h"
51
36
#include <drizzled/item/string.h>
52
37
#include <drizzled/item/int.h>
53
38
#include <drizzled/item/decimal.h>
54
39
#include <drizzled/item/float.h>
55
40
#include <drizzled/item/null.h>
56
#include <drizzled/temporal.h>
58
#include <drizzled/refresh_version.h>
60
#include "drizzled/table/singular.h"
62
#include "drizzled/table_proto.h"
42
#include <drizzled/table_proto.h>
48
using namespace drizzled;
64
49
using namespace std;
69
extern plugin::StorageEngine *heap_engine;
70
extern plugin::StorageEngine *myisam_engine;
72
/* Functions defined in this cursor */
50
using namespace drizzled;
52
/* Functions defined in this file */
54
void open_table_error(TableShare *share, int error, int db_errno,
55
myf errortype, int errarg);
74
57
/*************************************************************************/
76
// @note this should all be the destructor
77
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= ha_resolve_by_name(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= StorageEngine::getTableProto(share->normalized_path.str, &table);
1211
if (error != EEXIST)
1220
if (!table.IsInitialized())
1228
error= parse_table_proto(session, table, share);
1230
share->table_category= get_table_category(& share->db);
1233
session->status_var.opened_shares++;
1236
if (error && !error_given)
1238
share->error= error;
1239
share->open_table_error(error, (share->open_errno= my_errno), 0);
1247
Open a table based on a TableShare
1250
open_table_from_share()
1251
session Thread handler
1252
share Table definition
1253
alias Alias for table
1254
db_stat open flags (for example HA_OPEN_KEYFILE|
1255
HA_OPEN_RNDFILE..) can be 0 (example in
1257
prgflag READ_ALL etc..
1258
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1259
outparam result table
1260
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1261
if OTM_CREATE some errors are ignore
1262
if OTM_ALTER HA_OPEN is not called
1266
1 Error (see open_table_error)
1267
2 Error (see open_table_error)
1268
3 Wrong data in .frm file
1269
4 Error (see open_table_error)
1270
5 Error (see open_table_error: charset unavailable)
1271
7 Table definition has changed in engine
1274
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1275
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1276
Table *outparam, open_table_mode open_mode)
1279
uint32_t records, i, bitmap_size;
1280
bool error_reported= false;
1281
unsigned char *record, *bitmaps;
1284
/* Parsing of partitioning information from .frm needs session->lex set up. */
1285
assert(session->lex->is_lex_started);
1288
outparam->resetTable(session, share, db_stat);
1291
if (!(outparam->alias= strdup(alias)))
1294
/* Allocate handler */
1295
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1297
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1308
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1310
if (prgflag & (READ_ALL+EXTRA_RECORD))
1313
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1314
share->rec_buff_length * records)))
1319
/* We are probably in hard repair, and the buffers should not be used */
1320
outparam->record[0]= outparam->record[1]= share->default_values;
1324
outparam->record[0]= record;
1326
outparam->record[1]= record+ share->rec_buff_length;
1328
outparam->record[1]= outparam->record[0]; // Safety
1333
We need this because when we read var-length rows, we are not updating
1334
bytes after end of varchar
1338
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1339
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1341
memcpy(outparam->record[1], share->default_values,
1342
share->rec_buff_length);
1346
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1347
(uint32_t) ((share->fields+1)*
1351
outparam->field= field_ptr;
1353
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1355
outparam->null_flags= (unsigned char*) record+1;
1357
/* Setup copy of fields from share, but use the right alias and record */
1358
for (i= 0 ; i < share->fields; i++, field_ptr++)
1360
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1363
(*field_ptr)= 0; // End marker
1365
if (share->found_next_number_field)
1366
outparam->found_next_number_field=
1367
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1368
if (share->timestamp_field)
1369
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1372
/* Fix key->name and key_part->field */
1373
if (share->key_parts)
1375
KEY *key_info, *key_info_end;
1376
KEY_PART_INFO *key_part;
1378
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1379
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1381
outparam->key_info= key_info;
1382
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1384
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1385
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1388
for (key_info_end= key_info + share->keys ;
1389
key_info < key_info_end ;
1392
KEY_PART_INFO *key_part_end;
1394
key_info->table= outparam;
1395
key_info->key_part= key_part;
1397
for (key_part_end= key_part+ key_info->key_parts ;
1398
key_part < key_part_end ;
1401
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1403
if (field->key_length() != key_part->length &&
1404
!(field->flags & BLOB_FLAG))
1407
We are using only a prefix of the column as a key:
1408
Create a new field for the key part that matches the index
1410
field= key_part->field=field->new_field(&outparam->mem_root,
1412
field->field_length= key_part->length;
1418
/* Allocate bitmaps */
1420
bitmap_size= share->column_bitmap_size;
1421
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1423
outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1424
outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1425
outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1426
outparam->default_column_bitmaps();
1428
/* The table struct is now initialized; Open the table */
1430
if (db_stat && open_mode != OTM_ALTER)
1433
if ((ha_err= (outparam->file->
1434
ha_open(outparam, share->normalized_path.str,
1435
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1436
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1437
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1438
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1439
HA_OPEN_ABORT_IF_LOCKED :
1440
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1442
/* Set a flag if the table is crashed and it can be auto. repaired */
1443
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1444
outparam->file->auto_repair() &&
1445
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1449
case HA_ERR_NO_SUCH_TABLE:
1451
The table did not exists in storage engine, use same error message
1452
as if the .frm file didn't exist
1459
Too many files opened, use same error message as if the .frm
1466
outparam->file->print_error(ha_err, MYF(0));
1467
error_reported= true;
1468
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1476
#if defined(HAVE_purify)
1477
memset(bitmaps, 0, bitmap_size*3);
1480
session->status_var.opened_tables++;
1485
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1486
share->open_table_error(error, my_errno, 0);
1487
delete outparam->file;
1488
outparam->file= 0; // For easier error checking
1489
outparam->db_stat= 0;
1490
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1491
free((char*) outparam->alias);
1496
Free information allocated by openfrm
1500
table Table object to free
1501
free_share Is 1 if we also want to free table_share
1504
int Table::closefrm(bool free_share)
82
error= cursor->close();
1509
error= file->close();
1510
free((char*) alias);
87
1514
for (Field **ptr=field ; *ptr ; ptr++)
94
cursor= 0; /* For easier errorchecking */
1519
file= 0; /* For easier errorchecking */
1522
if (s->tmp_table == NO_TMP_TABLE)
1523
TableShare::release(s);
1525
s->free_table_share();
1527
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)
127
db_stat= db_stat_arg;
129
record[0]= (unsigned char *) NULL;
130
record[1]= (unsigned char *) NULL;
132
insert_values.clear();
134
next_number_field= NULL;
135
found_next_number_field= NULL;
136
timestamp_field= NULL;
138
pos_in_table_list= NULL;
148
derived_select_number= 0;
149
current_lock= F_UNLCK;
163
open_placeholder= false;
164
locked_by_name= false;
167
auto_increment_field_not_null= false;
168
alias_name_used= false;
171
quick_condition_rows= 0;
173
timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
178
covering_keys.reset();
183
keys_in_use_for_query.reset();
184
keys_in_use_for_group_by.reset();
185
keys_in_use_for_order_by.reset();
187
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
188
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
190
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
191
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
193
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
198
1533
/* Deallocate temporary blob storage */
1398
2931
session->mem_root= mem_root_save;
2932
table->free_tmp_table(session);
1404
2936
/****************************************************************************/
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;
2939
Create a reduced Table object with properly set up Field list from a
2940
list of field definitions.
2942
The created table doesn't have a table handler associated with
2943
it, has no keys, no group/distinct, no copy_funcs array.
2944
The sole purpose of this Table object is to use the power of Field
2945
class to read/write data to/from table->record[0]. Then one can store
2946
the record in any container (RB tree, hash, etc).
2947
The table is created in Session mem_root, so are the table's fields.
2948
Consequently, if you don't BLOB fields, you don't need to free it.
2950
@param session connection handle
2951
@param field_list list of column definitions
2954
0 if out of memory, Table object in case of success
2957
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
2959
uint32_t field_count= field_list.elements;
2960
uint32_t blob_count= 0;
2962
CreateField *cdef; /* column definition */
2963
uint32_t record_length= 0;
2964
uint32_t null_count= 0; /* number of columns which may be null */
2965
uint32_t null_pack_length; /* NULL representation array length */
2966
uint32_t *blob_field;
2967
unsigned char *bitmaps;
2971
if (!multi_alloc_root(session->mem_root,
2972
&table, sizeof(*table),
2973
&share, sizeof(*share),
2974
&field, (field_count + 1) * sizeof(Field*),
2975
&blob_field, (field_count+1) *sizeof(uint32_t),
2976
&bitmaps, bitmap_buffer_size(field_count)*2,
2980
memset(table, 0, sizeof(*table));
2981
memset(share, 0, sizeof(*share));
2982
table->field= field;
2984
share->blob_field= blob_field;
2985
share->fields= field_count;
2986
share->blob_ptr_size= portable_sizeof_char_ptr;
2987
table->setup_tmp_table_column_bitmaps(bitmaps);
2989
/* Create all fields and calculate the total length of record */
2990
List_iterator_fast<CreateField> it(field_list);
2991
while ((cdef= it++))
2993
*field= make_field(share,
2997
(cdef->flags & NOT_NULL_FLAG) ? false : true,
2998
(unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
2999
(cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3008
(*field)->init(table);
3009
record_length+= (*field)->pack_length();
3010
if (! ((*field)->flags & NOT_NULL_FLAG))
3013
if ((*field)->flags & BLOB_FLAG)
3014
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
3018
*field= NULL; /* mark the end of the list */
3019
share->blob_field[blob_count]= 0; /* mark the end of the list */
3020
share->blob_fields= blob_count;
3022
null_pack_length= (null_count + 7)/8;
3023
share->reclength= record_length + null_pack_length;
3024
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3025
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
3026
if (!table->record[0])
3029
if (null_pack_length)
3031
table->null_flags= (unsigned char*) table->record[0];
3032
share->null_fields= null_count;
3033
share->null_bytes= null_pack_length;
3036
table->in_use= session; /* field->reset() may access table->in_use */
3038
/* Set up field pointers */
3039
unsigned char *null_pos= table->record[0];
3040
unsigned char *field_pos= null_pos + share->null_bytes;
3041
uint32_t null_bit= 1;
3043
for (field= table->field; *field; ++field)
3045
Field *cur_field= *field;
3046
if ((cur_field->flags & NOT_NULL_FLAG))
3047
cur_field->move_field(field_pos);
3050
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
3052
if (null_bit == (1 << 8))
3060
field_pos+= cur_field->pack_length();
3065
for (field= table->field; *field; ++field)
3066
delete *field; /* just invokes field destructor */
3070
bool Table::open_tmp_table()
3073
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3074
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3076
file->print_error(error,MYF(0));
3080
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
3086
Create MyISAM temporary table
3089
create_myisam_tmp_table()
3090
keyinfo Description of the index (there is always one index)
3091
start_recinfo MyISAM's column descriptions
3092
recinfo INOUT End of MyISAM's column descriptions
3096
Create a MyISAM temporary table according to passed description. The is
3097
assumed to have one unique index or constraint.
3099
The passed array or MI_COLUMNDEF structures must have this form:
3101
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
3102
when there are many nullable columns)
3104
3. One free MI_COLUMNDEF element (*recinfo points here)
3106
This function may use the free element to create hash column for unique
3114
bool Table::create_myisam_tmp_table(KEY *keyinfo,
3115
MI_COLUMNDEF *start_recinfo,
3116
MI_COLUMNDEF **recinfo,
3121
MI_UNIQUEDEF uniquedef;
3122
TableShare *share= s;
3125
{ // Get keys for ni_create
3126
bool using_unique_constraint= 0;
3127
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3128
sizeof(*seg) * keyinfo->key_parts);
3132
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3133
if (keyinfo->key_length >= file->max_key_length() ||
3134
keyinfo->key_parts > file->max_key_parts() ||
3137
/* Can't create a key; Make a unique constraint instead of a key */
3140
using_unique_constraint=1;
3141
memset(&uniquedef, 0, sizeof(uniquedef));
3142
uniquedef.keysegs=keyinfo->key_parts;
3144
uniquedef.null_are_equal=1;
3146
/* Create extra column for hash value */
3147
memset(*recinfo, 0, sizeof(**recinfo));
3148
(*recinfo)->type= FIELD_CHECK;
3149
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
3151
share->reclength+=MI_UNIQUE_HASH_LENGTH;
3155
/* Create an unique key */
3156
memset(&keydef, 0, sizeof(keydef));
3157
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
3158
keydef.keysegs= keyinfo->key_parts;
3161
for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
3163
Field *key_field=keyinfo->key_part[i].field;
3165
seg->language= key_field->charset()->number;
3166
seg->length= keyinfo->key_part[i].length;
3167
seg->start= keyinfo->key_part[i].offset;
3168
if (key_field->flags & BLOB_FLAG)
3170
seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
3171
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3172
seg->bit_start= (uint8_t)(key_field->pack_length()
3173
- share->blob_ptr_size);
3174
seg->flag= HA_BLOB_PART;
3175
seg->length= 0; // Whole blob in unique constraint
3179
seg->type= keyinfo->key_part[i].type;
3181
if (!(key_field->flags & NOT_NULL_FLAG))
3183
seg->null_bit= key_field->null_bit;
3184
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
3186
We are using a GROUP BY on something that contains NULL
3187
In this case we have to tell MyISAM that two NULL should
3188
on INSERT be regarded at the same value
3190
if (!using_unique_constraint)
3191
keydef.flag|= HA_NULL_ARE_EQUAL;
3195
MI_CREATE_INFO create_info;
3196
memset(&create_info, 0, sizeof(create_info));
3198
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3200
create_info.data_file_length= ~(uint64_t) 0;
3202
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3203
(uint32_t) (*recinfo-start_recinfo),
3205
share->uniques, &uniquedef,
3207
HA_CREATE_TMP_TABLE)))
3209
file->print_error(error,MYF(0));
3213
status_var_increment(in_use->status_var.created_tmp_disk_tables);
3214
share->db_record_offset= 1;
3221
void Table::free_tmp_table(Session *session)
3223
MEM_ROOT own_root= mem_root;
3224
const char *save_proc_info;
3226
save_proc_info=session->get_proc_info();
3227
session->set_proc_info("removing tmp table");
3229
// Release latches since this can take a long time
3230
ha_release_temporary_latches(session);
3235
file->ha_drop_table(s->table_name.str);
3237
s->db_type()->deleteTable(session, s->table_name.str);
3242
for (Field **ptr= field ; *ptr ; ptr++)
3246
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3247
session->set_proc_info(save_proc_info);
3251
If a HEAP table gets full, create a MyISAM table and copy all rows
3255
bool create_myisam_from_heap(Session *session, Table *table,
3256
MI_COLUMNDEF *start_recinfo,
3257
MI_COLUMNDEF **recinfo,
3258
int error, bool ignore_last_dupp_key_error)
3262
const char *save_proc_info;
3265
if (table->s->db_type() != heap_engine ||
3266
error != HA_ERR_RECORD_FILE_FULL)
3268
table->file->print_error(error,MYF(0));
3272
// Release latches since this can take a long time
3273
ha_release_temporary_latches(session);
3277
new_table.s= &share;
3278
new_table.s->storage_engine= myisam_engine;
3279
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
3280
new_table.s->db_type())))
3281
return true; // End of memory
3283
save_proc_info=session->get_proc_info();
3284
session->set_proc_info("converting HEAP to MyISAM");
3286
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
3287
recinfo, session->lex->select_lex.options |
3290
if (new_table.open_tmp_table())
3292
if (table->file->indexes_are_disabled())
3293
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3294
table->file->ha_index_or_rnd_end();
3295
table->file->ha_rnd_init(1);
3298
new_table.file->extra(HA_EXTRA_NO_ROWS);
3299
new_table.no_rows=1;
3302
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3303
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3306
copy all old rows from heap table to MyISAM table
3307
This is the only code that uses record[1] to read/write but this
3308
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3310
while (!table->file->rnd_next(new_table.record[1]))
3312
write_err= new_table.file->ha_write_row(new_table.record[1]);
3316
/* copy row that filled HEAP table */
3317
if ((write_err=new_table.file->ha_write_row(table->record[0])))
3319
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3320
!ignore_last_dupp_key_error)
3324
/* remove heap table and change to use myisam table */
3325
(void) table->file->ha_rnd_end();
3326
(void) table->file->close(); // This deletes the table !
3329
new_table.s= table->s; // Keep old share
3333
table->file->change_table_ptr(table, table->s);
3334
table->use_all_columns();
3337
const char *new_proc_info=
3338
(!strcmp(save_proc_info,"Copying to tmp table") ?
3339
"Copying to tmp table on disk" : save_proc_info);
3340
session->set_proc_info(new_proc_info);
3345
table->file->print_error(write_err, MYF(0));
3346
(void) table->file->ha_rnd_end();
3347
(void) new_table.file->close();
3349
new_table.s->db_type()->deleteTable(session, new_table.s->table_name.str);
3351
delete new_table.file;
3352
session->set_proc_info(save_proc_info);
3353
table->mem_root= new_table.mem_root;
3357
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
3359
my_bitmap_map *old= bitmap->getBitmap();
3360
bitmap->setBitmap(s->all_set.getBitmap());
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
3364
void Table::restore_column_map(my_bitmap_map *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
3366
read_set->setBitmap(old);
1436
3369
uint32_t Table::find_shortest_key(const key_map *usable_keys)