12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
/* Some general useful functions */
19
#include <drizzled/server_includes.h>
28
20
#include <drizzled/error.h>
29
21
#include <drizzled/gettext.h>
31
#include "drizzled/plugin/transactional_storage_engine.h"
32
#include "drizzled/plugin/authorization.h"
23
#include <drizzled/sj_tmp_table.h>
33
24
#include <drizzled/nested_join.h>
25
#include <drizzled/data_home.h>
34
26
#include <drizzled/sql_parse.h>
35
27
#include <drizzled/item/sum.h>
36
28
#include <drizzled/table_list.h>
37
29
#include <drizzled/session.h>
38
30
#include <drizzled/sql_base.h>
39
#include <drizzled/sql_select.h>
40
31
#include <drizzled/field/blob.h>
41
32
#include <drizzled/field/varstring.h>
42
33
#include <drizzled/field/double.h>
43
37
#include <drizzled/unireg.h>
44
38
#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
40
#include <drizzled/item/string.h>
52
41
#include <drizzled/item/int.h>
53
42
#include <drizzled/item/decimal.h>
54
43
#include <drizzled/item/float.h>
55
44
#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"
64
47
using namespace std;
69
extern plugin::StorageEngine *heap_engine;
70
extern plugin::StorageEngine *myisam_engine;
72
/* Functions defined in this cursor */
49
/* Keyword for parsing virtual column functions */
50
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
52
/* Functions defined in this file */
54
void open_table_error(TableShare *share, int error, int db_errno,
55
myf errortype, int errarg);
56
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
57
uint32_t types, char **names);
74
59
/*************************************************************************/
76
// @note this should all be the destructor
77
int Table::delete_table(bool free_share)
61
/* Get column name from column hash */
63
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
65
*length= (uint32_t) strlen((*buff)->field_name);
66
return (unsigned char*) (*buff)->field_name;
71
Returns pointer to '.frm' extension of the file name.
78
Checks file name part starting with the rightmost '.' character,
79
and returns it if it is equal to '.frm'.
82
It is a good idea to get rid of this function modifying the code
83
to garantee that the functions presently calling fn_rext() always
84
get arguments in the same format: either with '.frm' or without '.frm'.
87
Pointer to the '.frm' extension. If there is no extension,
88
or extension is not '.frm', pointer at the end of file name.
91
char *fn_rext(char *name)
93
char *res= strrchr(name, '.');
94
if (res && !strcmp(res, ".dfe"))
96
return name + strlen(name);
99
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
102
assert(name != NULL);
104
if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
105
(my_strcasecmp(system_charset_info,
106
INFORMATION_SCHEMA_NAME.c_str(),
109
return TABLE_CATEGORY_INFORMATION;
112
return TABLE_CATEGORY_USER;
117
Allocate a setup TableShare structure
121
TableList Take database and table name from there
122
key Table cache key (db \0 table_name \0...)
123
key_length Length of key
126
0 Error (out of memory)
130
TableShare *alloc_table_share(TableList *table_list, char *key,
135
char *key_buff, *path_buff;
136
char path[FN_REFLEN];
137
uint32_t path_length;
139
path_length= build_table_filename(path, sizeof(path) - 1,
141
table_list->table_name, "", 0);
142
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
143
if (multi_alloc_root(&mem_root,
144
&share, sizeof(*share),
145
&key_buff, key_length,
146
&path_buff, path_length + 1,
149
memset(share, 0, sizeof(*share));
151
share->set_table_cache_key(key_buff, key, key_length);
153
share->path.str= path_buff;
154
share->path.length= path_length;
155
strcpy(share->path.str, path);
156
share->normalized_path.str= share->path.str;
157
share->normalized_path.length= path_length;
159
share->version= refresh_version;
161
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
162
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
163
pthread_cond_init(&share->cond, NULL);
169
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
171
enum_field_types field_type;
173
switch(proto_field_type)
175
case drizzled::message::Table::Field::TINYINT:
176
field_type= DRIZZLE_TYPE_TINY;
178
case drizzled::message::Table::Field::INTEGER:
179
field_type= DRIZZLE_TYPE_LONG;
181
case drizzled::message::Table::Field::DOUBLE:
182
field_type= DRIZZLE_TYPE_DOUBLE;
184
case drizzled::message::Table::Field::TIMESTAMP:
185
field_type= DRIZZLE_TYPE_TIMESTAMP;
187
case drizzled::message::Table::Field::BIGINT:
188
field_type= DRIZZLE_TYPE_LONGLONG;
190
case drizzled::message::Table::Field::DATETIME:
191
field_type= DRIZZLE_TYPE_DATETIME;
193
case drizzled::message::Table::Field::DATE:
194
field_type= DRIZZLE_TYPE_DATE;
196
case drizzled::message::Table::Field::VARCHAR:
197
field_type= DRIZZLE_TYPE_VARCHAR;
199
case drizzled::message::Table::Field::DECIMAL:
200
field_type= DRIZZLE_TYPE_NEWDECIMAL;
202
case drizzled::message::Table::Field::ENUM:
203
field_type= DRIZZLE_TYPE_ENUM;
205
case drizzled::message::Table::Field::BLOB:
206
field_type= DRIZZLE_TYPE_BLOB;
209
field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
216
Item * default_value_item(enum_field_types field_type,
217
const CHARSET_INFO *charset,
218
bool default_null, const string *default_value,
219
const string *default_bin_value)
221
Item *default_item= NULL;
226
return new Item_null();
231
case DRIZZLE_TYPE_TINY:
232
case DRIZZLE_TYPE_LONG:
233
case DRIZZLE_TYPE_LONGLONG:
234
default_item= new Item_int(default_value->c_str(),
235
(int64_t) my_strtoll10(default_value->c_str(),
238
default_value->length());
240
case DRIZZLE_TYPE_DOUBLE:
241
default_item= new Item_float(default_value->c_str(),
242
default_value->length());
244
case DRIZZLE_TYPE_NULL:
246
case DRIZZLE_TYPE_TIMESTAMP:
247
case DRIZZLE_TYPE_DATETIME:
248
case DRIZZLE_TYPE_DATE:
249
if (default_value->compare("NOW()") == 0)
251
case DRIZZLE_TYPE_ENUM:
252
default_item= new Item_string(default_value->c_str(),
253
default_value->length(),
254
system_charset_info);
256
case DRIZZLE_TYPE_VARCHAR:
257
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
258
if(charset==&my_charset_bin)
260
default_item= new Item_string(default_bin_value->c_str(),
261
default_bin_value->length(),
266
default_item= new Item_string(default_value->c_str(),
267
default_value->length(),
268
system_charset_info);
271
case DRIZZLE_TYPE_NEWDECIMAL:
272
default_item= new Item_decimal(default_value->c_str(),
273
default_value->length(),
274
system_charset_info);
281
int parse_table_proto(Session *session, drizzled::message::Table &table, TableShare *share)
284
handler *handler_file= NULL;
287
LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
288
strlen(table.engine().name().c_str()) };
289
share->storage_engine= ha_resolve_by_name(session, &engine_name);
292
share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
294
drizzled::message::Table::TableOptions table_options;
296
if(table.has_options())
297
table_options= table.options();
299
uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
301
if(table_options.has_pack_keys())
303
if(table_options.pack_keys())
304
db_create_options|= HA_OPTION_PACK_KEYS;
306
db_create_options|= HA_OPTION_NO_PACK_KEYS;
309
if(table_options.pack_record())
310
db_create_options|= HA_OPTION_PACK_RECORD;
312
if(table_options.has_checksum())
314
if(table_options.checksum())
315
db_create_options|= HA_OPTION_CHECKSUM;
317
db_create_options|= HA_OPTION_NO_CHECKSUM;
320
if(table_options.has_delay_key_write())
322
if(table_options.delay_key_write())
323
db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
325
db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
328
/* db_create_options was stored as 2 bytes in FRM
329
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
331
share->db_create_options= (db_create_options & 0x0000FFFF);
332
share->db_options_in_use= share->db_create_options;
335
share->avg_row_length= table_options.has_avg_row_length() ?
336
table_options.avg_row_length() : 0;
338
share->page_checksum= table_options.has_page_checksum() ?
339
(table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
342
share->row_type= table_options.has_row_type() ?
343
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
345
share->block_size= table_options.has_block_size() ?
346
table_options.block_size() : 0;
348
share->table_charset= get_charset(table_options.has_collation_id()?
349
table_options.collation_id() : 0);
351
if (!share->table_charset)
353
/* unknown charset in head[38] or pre-3.23 frm */
354
if (use_mb(default_charset_info))
356
/* Warn that we may be changing the size of character columns */
357
errmsg_printf(ERRMSG_LVL_WARN,
358
_("'%s' had no or invalid character set, "
359
"and default character set is multi-byte, "
360
"so character column sizes may have changed"),
363
share->table_charset= default_charset_info;
366
share->db_record_offset= 1;
368
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
370
share->db_low_byte_first= true;
372
share->max_rows= table_options.has_max_rows() ?
373
table_options.max_rows() : 0;
375
share->min_rows= table_options.has_min_rows() ?
376
table_options.min_rows() : 0;
378
share->keys= table.indexes_size();
381
for(int indx= 0; indx < table.indexes_size(); indx++)
382
share->key_parts+= table.indexes(indx).index_part_size();
384
share->key_info= (KEY*) alloc_root(&share->mem_root,
385
table.indexes_size() * sizeof(KEY)
386
+share->key_parts*sizeof(KEY_PART_INFO));
388
KEY_PART_INFO *key_part;
390
key_part= reinterpret_cast<KEY_PART_INFO*>
391
(share->key_info+table.indexes_size());
394
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
395
sizeof(ulong*)*share->key_parts);
397
share->keynames.count= table.indexes_size();
398
share->keynames.name= NULL;
399
share->keynames.type_names= (const char**)
400
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
402
share->keynames.type_lengths= (unsigned int*)
403
alloc_root(&share->mem_root,
404
sizeof(unsigned int) * (table.indexes_size()+1));
406
share->keynames.type_names[share->keynames.count]= NULL;
407
share->keynames.type_lengths[share->keynames.count]= 0;
409
KEY* keyinfo= share->key_info;
410
for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
412
drizzled::message::Table::Index indx= table.indexes(keynr);
418
keyinfo->flags|= HA_NOSAME;
420
if(indx.has_options())
422
drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
423
if(indx_options.pack_key())
424
keyinfo->flags|= HA_PACK_KEY;
426
if(indx_options.var_length_key())
427
keyinfo->flags|= HA_VAR_LENGTH_PART;
429
if(indx_options.null_part_key())
430
keyinfo->flags|= HA_NULL_PART_KEY;
432
if(indx_options.binary_pack_key())
433
keyinfo->flags|= HA_BINARY_PACK_KEY;
435
if(indx_options.has_partial_segments())
436
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
438
if(indx_options.auto_generated_key())
439
keyinfo->flags|= HA_GENERATED_KEY;
441
if(indx_options.has_key_block_size())
443
keyinfo->flags|= HA_USES_BLOCK_SIZE;
444
keyinfo->block_size= indx_options.key_block_size();
448
keyinfo->block_size= 0;
455
case drizzled::message::Table::Index::UNKNOWN_INDEX:
456
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
458
case drizzled::message::Table::Index::BTREE:
459
keyinfo->algorithm= HA_KEY_ALG_BTREE;
461
case drizzled::message::Table::Index::RTREE:
462
keyinfo->algorithm= HA_KEY_ALG_RTREE;
464
case drizzled::message::Table::Index::HASH:
465
keyinfo->algorithm= HA_KEY_ALG_HASH;
467
case drizzled::message::Table::Index::FULLTEXT:
468
keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
471
/* TODO: suitable warning ? */
472
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
476
keyinfo->key_length= indx.key_length();
478
keyinfo->key_parts= indx.index_part_size();
480
keyinfo->key_part= key_part;
481
keyinfo->rec_per_key= rec_per_key;
483
for(unsigned int partnr= 0;
484
partnr < keyinfo->key_parts;
485
partnr++, key_part++)
487
drizzled::message::Table::Index::IndexPart part;
488
part= indx.index_part(partnr);
492
key_part->field= NULL;
493
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
494
key_part->null_bit= 0;
495
/* key_part->null_offset is only set if null_bit (see later) */
496
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
497
/* key_part->type ???? */
498
key_part->key_part_flag= 0;
499
if(part.has_in_reverse_order())
500
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
502
key_part->length= part.compare_length();
504
key_part->store_length= key_part->length;
506
/* key_part->offset is set later */
507
key_part->key_type= part.key_type();
511
if(!indx.has_comment())
513
keyinfo->comment.length= 0;
514
keyinfo->comment.str= NULL;
518
keyinfo->flags|= HA_USES_COMMENT;
519
keyinfo->comment.length= indx.comment().length();
520
keyinfo->comment.str= strmake_root(&share->mem_root,
521
indx.comment().c_str(),
522
keyinfo->comment.length);
525
keyinfo->name= strmake_root(&share->mem_root,
527
indx.name().length());
529
share->keynames.type_names[keynr]= keyinfo->name;
530
share->keynames.type_lengths[keynr]= indx.name().length();
533
share->keys_for_keyread.reset();
534
set_prefix(share->keys_in_use, share->keys);
536
if(table_options.has_connect_string())
538
size_t len= table_options.connect_string().length();
539
const char* str= table_options.connect_string().c_str();
541
share->connect_string.length= len;
542
share->connect_string.str= strmake_root(&share->mem_root, str, len);
545
if(table_options.has_comment())
547
size_t len= table_options.comment().length();
548
const char* str= table_options.comment().c_str();
550
share->comment.length= len;
551
share->comment.str= strmake_root(&share->mem_root, str, len);
554
share->key_block_size= table_options.has_key_block_size() ?
555
table_options.key_block_size() : 0;
557
share->fields= table.field_size();
560
share->field= (Field**) alloc_root(&share->mem_root,
561
((share->fields+1) * sizeof(Field*)));
562
share->field[share->fields]= NULL;
564
uint32_t null_fields= 0;
567
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
568
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
570
assert(field_offsets && field_pack_length); // TODO: fixme
572
uint32_t interval_count= 0;
573
uint32_t interval_parts= 0;
575
uint32_t stored_columns_reclength= 0;
577
for (unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
579
drizzled::message::Table::Field pfield= table.field(fieldnr);
580
if(pfield.has_constraints() && pfield.constraints().is_nullable())
583
bool field_is_stored= true;
585
enum_field_types drizzle_field_type=
586
proto_field_type_to_drizzle_type(pfield.type());
588
field_offsets[fieldnr]= stored_columns_reclength;
590
/* the below switch is very similar to
591
Create_field::create_length_to_internal_length in field.cc
592
(which should one day be replace by just this code)
594
switch(drizzle_field_type)
596
case DRIZZLE_TYPE_BLOB:
597
case DRIZZLE_TYPE_VARCHAR:
599
drizzled::message::Table::Field::StringFieldOptions field_options=
600
pfield.string_options();
602
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
603
field_options.collation_id() : 0);
606
cs= default_charset_info;
608
field_pack_length[fieldnr]=
609
calc_pack_length(drizzle_field_type,
610
field_options.length() * cs->mbmaxlen);
614
case DRIZZLE_TYPE_ENUM:
616
drizzled::message::Table::Field::SetFieldOptions field_options=
617
pfield.set_options();
619
field_pack_length[fieldnr]=
620
get_enum_pack_length(field_options.field_value_size());
623
interval_parts+= field_options.field_value_size();
626
case DRIZZLE_TYPE_NEWDECIMAL:
628
drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
630
field_pack_length[fieldnr]=
631
my_decimal_get_binary_size(fo.precision(), fo.scale());
635
/* Zero is okay here as length is fixed for other types. */
636
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
639
share->reclength+= field_pack_length[fieldnr];
642
stored_columns_reclength+= field_pack_length[fieldnr];
645
/* data_offset added to stored_rec_length later */
646
share->stored_rec_length= stored_columns_reclength;
648
/* fix up offsets for non-stored fields (at end of record) */
649
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
651
drizzled::message::Table::Field pfield= table.field(fieldnr);
653
bool field_is_stored= true;
657
field_offsets[fieldnr]= stored_columns_reclength;
658
stored_columns_reclength+= field_pack_length[fieldnr];
661
share->null_fields= null_fields;
663
ulong null_bits= null_fields;
664
if(!table_options.pack_record())
666
ulong data_offset= (null_bits + 7)/8;
669
share->reclength+= data_offset;
670
share->stored_rec_length+= data_offset;
672
ulong rec_buff_length;
674
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
675
share->rec_buff_length= rec_buff_length;
677
unsigned char* record= NULL;
679
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
683
memset(record, 0, rec_buff_length);
687
if(!table_options.pack_record())
689
null_count++; // one bit for delete mark.
693
share->default_values= record;
697
share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
698
interval_count*sizeof(TYPELIB));
701
share->intervals= NULL;
703
share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
704
(share->fields+1)*sizeof(char*));
706
share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
707
(share->fields+1)*sizeof(unsigned int));
709
share->fieldnames.type_names[share->fields]= NULL;
710
share->fieldnames.type_lengths[share->fields]= 0;
711
share->fieldnames.count= share->fields;
714
/* Now fix the TYPELIBs for the intervals (enum values)
718
uint32_t interval_nr= 0;
720
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
722
drizzled::message::Table::Field pfield= table.field(fieldnr);
725
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
726
pfield.name().c_str(),
727
pfield.name().length());
729
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
732
if(pfield.type() != drizzled::message::Table::Field::ENUM)
735
drizzled::message::Table::Field::SetFieldOptions field_options=
736
pfield.set_options();
738
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
739
field_options.collation_id() : 0);
742
charset= default_charset_info;
744
TYPELIB *t= &(share->intervals[interval_nr]);
746
t->type_names= (const char**)alloc_root(&share->mem_root,
747
(field_options.field_value_size()+1)*sizeof(char*));
749
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
750
(field_options.field_value_size()+1)*sizeof(unsigned int));
752
t->type_names[field_options.field_value_size()]= NULL;
753
t->type_lengths[field_options.field_value_size()]= 0;
755
t->count= field_options.field_value_size();
758
for(int n=0; n < field_options.field_value_size(); n++)
760
t->type_names[n]= strmake_root(&share->mem_root,
761
field_options.field_value(n).c_str(),
762
field_options.field_value(n).length());
764
/* Go ask the charset what the length is as for "" length=1
765
and there's stripping spaces or some other crack going on.
768
lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
769
field_options.field_value(n).length());
770
t->type_lengths[n]= lengthsp;
776
/* and read the fields */
779
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
782
use_hash= !hash_init(&share->name_hash,
785
(hash_get_key) get_field_name, 0, 0);
787
unsigned char* null_pos= record;;
788
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
790
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
792
drizzled::message::Table::Field pfield= table.field(fieldnr);
794
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
796
switch(pfield.format())
798
case drizzled::message::Table::Field::DefaultFormat:
799
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
801
case drizzled::message::Table::Field::FixedFormat:
802
column_format= COLUMN_FORMAT_TYPE_FIXED;
804
case drizzled::message::Table::Field::DynamicFormat:
805
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
811
Field::utype unireg_type= Field::NONE;
813
if(pfield.has_numeric_options()
814
&& pfield.numeric_options().is_autoincrement())
816
unireg_type= Field::NEXT_NUMBER;
819
if(pfield.has_options()
820
&& pfield.options().has_default_value()
821
&& pfield.options().default_value().compare("NOW()")==0)
823
if(pfield.options().has_update_value()
824
&& pfield.options().update_value().compare("NOW()")==0)
826
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
828
else if (!pfield.options().has_update_value())
830
unireg_type= Field::TIMESTAMP_DN_FIELD;
833
assert(1); // Invalid update value.
835
else if (pfield.has_options()
836
&& pfield.options().has_update_value()
837
&& pfield.options().update_value().compare("NOW()")==0)
839
unireg_type= Field::TIMESTAMP_UN_FIELD;
843
if(!pfield.has_comment())
845
comment.str= (char*)"";
850
size_t len= pfield.comment().length();
851
const char* str= pfield.comment().c_str();
853
comment.str= strmake_root(&share->mem_root, str, len);
857
enum_field_types field_type;
859
field_type= proto_field_type_to_drizzle_type(pfield.type());
861
const CHARSET_INFO *charset= &my_charset_bin;
863
if(field_type==DRIZZLE_TYPE_BLOB
864
|| field_type==DRIZZLE_TYPE_VARCHAR)
866
drizzled::message::Table::Field::StringFieldOptions field_options=
867
pfield.string_options();
869
charset= get_charset(field_options.has_collation_id()?
870
field_options.collation_id() : 0);
873
charset= default_charset_info;
877
if(field_type==DRIZZLE_TYPE_ENUM)
879
drizzled::message::Table::Field::SetFieldOptions field_options=
880
pfield.set_options();
882
charset= get_charset(field_options.has_collation_id()?
883
field_options.collation_id() : 0);
886
charset= default_charset_info;
890
Item *default_value= NULL;
892
if(pfield.options().has_default_value()
893
|| pfield.options().has_default_null()
894
|| pfield.options().has_default_bin_value())
896
default_value= default_value_item(field_type,
898
pfield.options().default_null(),
899
&pfield.options().default_value(),
900
&pfield.options().default_bin_value());
903
uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
905
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
906
memset(&temp_table, 0, sizeof(temp_table));
908
temp_table.in_use= session;
909
temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
910
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
912
Field* f= make_field(share, &share->mem_root,
913
record+field_offsets[fieldnr]+data_offset,
914
pfield.options().length(),
920
(Field::utype) MTYP_TYPENR(unireg_type),
921
((field_type==DRIZZLE_TYPE_ENUM)?
922
share->intervals+(interval_nr++)
924
share->fieldnames.type_names[fieldnr]);
926
share->field[fieldnr]= f;
928
f->init(&temp_table); /* blob default values need table obj */
930
if(!(f->flags & NOT_NULL_FLAG))
932
*f->null_ptr|= f->null_bit;
933
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
940
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
941
session->count_cuted_fields= CHECK_FIELD_WARN;
942
int res= default_value->save_in_field(f, 1);
943
session->count_cuted_fields= old_count_cuted_fields;
944
if (res != 0 && res != 3)
946
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
951
else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
952
(f->flags & NOT_NULL_FLAG))
955
f->store((int64_t) 1, true);
960
/* hack to undo f->init() */
964
f->field_index= fieldnr;
967
&& !(f->unireg_check==Field::NEXT_NUMBER)
968
&& (f->flags & NOT_NULL_FLAG)
969
&& (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
970
f->flags|= NO_DEFAULT_VALUE_FLAG;
972
if(f->unireg_check == Field::NEXT_NUMBER)
973
share->found_next_number_field= &(share->field[fieldnr]);
975
if(share->timestamp_field == f)
976
share->timestamp_field_offset= fieldnr;
978
if (use_hash) /* supposedly this never fails... but comments lie */
979
(void) my_hash_insert(&share->name_hash,
980
(unsigned char*)&(share->field[fieldnr]));
983
keyinfo= share->key_info;
984
for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
986
key_part= keyinfo->key_part;
988
for(unsigned int partnr= 0;
989
partnr < keyinfo->key_parts;
990
partnr++, key_part++)
992
/* Fix up key_part->offset by adding data_offset.
993
We really should compute offset as well.
994
But at least this way we are a little better. */
995
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1000
We need to set the unused bits to 1. If the number of bits is a multiple
1001
of 8 there are no unused bits.
1005
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1007
share->null_bytes= (null_pos - (unsigned char*) record +
1008
(null_bit_pos + 7) / 8);
1010
share->last_null_bit_pos= null_bit_pos;
1012
free(field_offsets);
1013
free(field_pack_length);
1015
if(!(handler_file= get_new_handler(share, session->mem_root,
1020
if (share->key_parts)
1022
uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
1023
&share->keynames, 3) - 1);
1025
int64_t ha_option= handler_file->ha_table_flags();
1027
keyinfo= share->key_info;
1028
key_part= keyinfo->key_part;
1030
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1032
uint32_t usable_parts= 0;
1034
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1037
If the UNIQUE key doesn't have NULL columns and is not a part key
1038
declare this as a primary key.
1041
for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
1043
uint32_t fieldnr= key_part[i].fieldnr;
1045
share->field[fieldnr-1]->null_ptr ||
1046
share->field[fieldnr-1]->key_length() !=
1049
primary_key=MAX_KEY; // Can't be used
1055
for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1058
if (!key_part->fieldnr)
1060
// error= 4; // Wrong file
1061
abort(); // goto err;
1063
field= key_part->field= share->field[key_part->fieldnr-1];
1064
key_part->type= field->key_type();
1065
if (field->null_ptr)
1067
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1068
share->default_values);
1069
key_part->null_bit= field->null_bit;
1070
key_part->store_length+=HA_KEY_NULL_LENGTH;
1071
keyinfo->flags|=HA_NULL_PART_KEY;
1072
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1073
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1075
if (field->type() == DRIZZLE_TYPE_BLOB ||
1076
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1078
if (field->type() == DRIZZLE_TYPE_BLOB)
1079
key_part->key_part_flag|= HA_BLOB_PART;
1081
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1082
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1083
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1084
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1086
if (i == 0 && key != primary_key)
1087
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1088
(keyinfo->key_parts == 1)) ?
1089
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1091
field->key_start.set(key);
1092
if (field->key_length() == key_part->length &&
1093
!(field->flags & BLOB_FLAG))
1095
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1097
share->keys_for_keyread.set(key);
1098
field->part_of_key.set(key);
1099
field->part_of_key_not_clustered.set(key);
1101
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1102
field->part_of_sortkey.set(key);
1104
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1106
usable_parts++; // For FILESORT
1107
field->flags|= PART_KEY_FLAG;
1108
if (key == primary_key)
1110
field->flags|= PRI_KEY_FLAG;
1112
If this field is part of the primary key and all keys contains
1113
the primary key, then we can use any key to find this column
1115
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1117
field->part_of_key= share->keys_in_use;
1118
if (field->part_of_sortkey.test(key))
1119
field->part_of_sortkey= share->keys_in_use;
1122
if (field->key_length() != key_part->length)
1124
key_part->key_part_flag|= HA_PART_KEY_SEG;
1127
keyinfo->usable_key_parts= usable_parts; // Filesort
1129
set_if_bigger(share->max_key_length,keyinfo->key_length+
1130
keyinfo->key_parts);
1131
share->total_key_length+= keyinfo->key_length;
1133
MERGE tables do not have unique indexes. But every key could be
1134
an unique index on the underlying MyISAM table. (Bug #10400)
1136
if ((keyinfo->flags & HA_NOSAME) ||
1137
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1138
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1140
if (primary_key < MAX_KEY &&
1141
(share->keys_in_use.test(primary_key)))
1143
share->primary_key= primary_key;
1145
If we are using an integer as the primary key then allow the user to
1146
refer to it as '_rowid'
1148
if (share->key_info[primary_key].key_parts == 1)
1150
Field *field= share->key_info[primary_key].key_part[0].field;
1151
if (field && field->result_type() == INT_RESULT)
1153
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1154
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1161
share->primary_key = MAX_KEY; // we do not have a primary key
1164
share->primary_key= MAX_KEY;
1166
if (share->found_next_number_field)
1168
Field *reg_field= *share->found_next_number_field;
1169
if ((int) (share->next_number_index= (uint32_t)
1170
find_ref_key(share->key_info, share->keys,
1171
share->default_values, reg_field,
1172
&share->next_number_key_offset,
1173
&share->next_number_keypart)) < 0)
1175
/* Wrong field definition */
1180
reg_field->flags |= AUTO_INCREMENT_FLAG;
1183
if (share->blob_fields)
1188
/* Store offsets to blob fields to find them fast */
1189
if (!(share->blob_field= save=
1190
(uint*) alloc_root(&share->mem_root,
1191
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1193
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1195
if ((*ptr)->flags & BLOB_FLAG)
1200
share->db_low_byte_first= handler_file->low_byte_first();
1201
share->all_set.set();
1204
delete handler_file;
1208
share->error= error;
1209
share->open_errno= my_errno;
1211
hash_free(&share->name_hash);
1213
delete handler_file;
1214
open_table_error(share, error, share->open_errno, 0);
1219
Read table definition from a binary / text based .frm file
1223
session Thread handler
1224
share Fill this with table definition
1227
This function is called when the table definition is not cached in
1229
The data is returned in 'share', which is alloced by
1230
alloc_table_share().. The code assumes that share is initialized.
1234
1 Error (see open_table_error)
1235
2 Error (see open_table_error)
1236
3 Wrong data in .frm file
1237
4 Error (see open_table_error)
1238
5 Error (see open_table_error: charset unavailable)
1239
6 Unknown .frm version
1242
int open_table_def(Session *session, TableShare *share)
1246
string proto_path("");
1251
proto_path.reserve(FN_REFLEN);
1252
proto_path.append(share->normalized_path.str);
1254
proto_path.append(".dfe");
1256
drizzled::message::Table table;
1258
if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
1267
if(!table.IsInitialized())
1275
error= parse_table_proto(session, table, share);
1277
share->table_category= get_table_category(& share->db, & share->table_name);
1280
session->status_var.opened_shares++;
1283
if (error && !error_given)
1285
share->error= error;
1286
open_table_error(share, error, (share->open_errno= my_errno), 0);
1294
Open a table based on a TableShare
1297
open_table_from_share()
1298
session Thread handler
1299
share Table definition
1300
alias Alias for table
1301
db_stat open flags (for example HA_OPEN_KEYFILE|
1302
HA_OPEN_RNDFILE..) can be 0 (example in
1304
prgflag READ_ALL etc..
1305
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1306
outparam result table
1307
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1308
if OTM_CREATE some errors are ignore
1309
if OTM_ALTER HA_OPEN is not called
1313
1 Error (see open_table_error)
1314
2 Error (see open_table_error)
1315
3 Wrong data in .frm file
1316
4 Error (see open_table_error)
1317
5 Error (see open_table_error: charset unavailable)
1318
7 Table definition has changed in engine
1321
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1322
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1323
Table *outparam, open_table_mode open_mode)
1326
uint32_t records, i;
1327
bool error_reported= false;
1328
unsigned char *record;
1331
/* Parsing of partitioning information from .frm needs session->lex set up. */
1332
assert(session->lex->is_lex_started);
1335
memset(outparam, 0, sizeof(*outparam));
1336
outparam->in_use= session;
1338
outparam->db_stat= db_stat;
1339
outparam->write_row_record= NULL;
1341
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1343
if (!(outparam->alias= strdup(alias)))
1345
outparam->quick_keys.reset();
1346
outparam->covering_keys.reset();
1347
outparam->keys_in_use_for_query.reset();
1349
/* Allocate handler */
1351
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1353
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1363
outparam->reginfo.lock_type= TL_UNLOCK;
1364
outparam->current_lock= F_UNLCK;
1366
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1368
if (prgflag & (READ_ALL+EXTRA_RECORD))
1371
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1372
share->rec_buff_length * records)))
1373
goto err; /* purecov: inspected */
1377
/* We are probably in hard repair, and the buffers should not be used */
1378
outparam->record[0]= outparam->record[1]= share->default_values;
1382
outparam->record[0]= record;
1384
outparam->record[1]= record+ share->rec_buff_length;
1386
outparam->record[1]= outparam->record[0]; // Safety
1391
We need this because when we read var-length rows, we are not updating
1392
bytes after end of varchar
1396
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1397
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1399
memcpy(outparam->record[1], share->default_values,
1400
share->rec_buff_length);
1404
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1405
(uint32_t) ((share->fields+1)*
1407
goto err; /* purecov: inspected */
1409
outparam->field= field_ptr;
1411
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1413
outparam->null_flags= (unsigned char*) record+1;
1415
/* Setup copy of fields from share, but use the right alias and record */
1416
for (i=0 ; i < share->fields; i++, field_ptr++)
1418
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1421
(*field_ptr)= 0; // End marker
1423
if (share->found_next_number_field)
1424
outparam->found_next_number_field=
1425
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1426
if (share->timestamp_field)
1427
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1430
/* Fix key->name and key_part->field */
1431
if (share->key_parts)
1433
KEY *key_info, *key_info_end;
1434
KEY_PART_INFO *key_part;
1436
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1437
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1439
outparam->key_info= key_info;
1440
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1442
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1443
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1446
for (key_info_end= key_info + share->keys ;
1447
key_info < key_info_end ;
1450
KEY_PART_INFO *key_part_end;
1452
key_info->table= outparam;
1453
key_info->key_part= key_part;
1455
for (key_part_end= key_part+ key_info->key_parts ;
1456
key_part < key_part_end ;
1459
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1461
if (field->key_length() != key_part->length &&
1462
!(field->flags & BLOB_FLAG))
1465
We are using only a prefix of the column as a key:
1466
Create a new field for the key part that matches the index
1468
field= key_part->field=field->new_field(&outparam->mem_root,
1470
field->field_length= key_part->length;
1476
/* Allocate bitmaps */
1477
outparam->default_column_bitmaps();
1479
/* The table struct is now initialized; Open the table */
1481
if (db_stat && open_mode != OTM_ALTER)
1484
if ((ha_err= (outparam->file->
1485
ha_open(outparam, share->normalized_path.str,
1486
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1487
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1488
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1489
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1490
HA_OPEN_ABORT_IF_LOCKED :
1491
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1493
/* Set a flag if the table is crashed and it can be auto. repaired */
1494
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1495
outparam->file->auto_repair() &&
1496
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1500
case HA_ERR_NO_SUCH_TABLE:
1502
The table did not exists in storage engine, use same error message
1503
as if the .frm file didn't exist
1510
Too many files opened, use same error message as if the .frm
1517
outparam->file->print_error(ha_err, MYF(0));
1518
error_reported= true;
1519
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1523
goto err; /* purecov: inspected */
1527
#if defined(HAVE_purify)
1528
memset(bitmaps, 0, bitmap_size*3);
1531
session->status_var.opened_tables++;
1536
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1537
open_table_error(share, error, my_errno, 0);
1538
delete outparam->file;
1539
outparam->file= 0; // For easier error checking
1540
outparam->db_stat=0;
1541
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1542
free((char*) outparam->alias);
1546
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
1547
uint32_t Table::tmpkeyval()
1549
return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
1553
Free information allocated by openfrm
1557
table Table object to free
1558
free_share Is 1 if we also want to free table_share
1561
int Table::closefrm(bool free_share)
82
error= cursor->close();
1566
error= file->close();
1567
free((char*) alias);
87
1571
for (Field **ptr=field ; *ptr ; ptr++)
94
cursor= 0; /* For easier errorchecking */
1576
file= 0; /* For easier errorchecking */
1579
if (s->tmp_table == NO_TMP_TABLE)
1580
release_table_share(s, RELEASE_NORMAL);
1582
s->free_table_share();
1584
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
1590
/* Deallocate temporary blob storage */
203
1595
for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
207
((Field_blob*) table->getField(*ptr))->free();
212
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
214
TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
1598
((Field_blob*) table->field[*ptr])->free();
1602
/* Find where a form starts */
1603
/* if formname is NULL then only formnames is read */
1605
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
1607
uint32_t a_length,names,length;
1608
unsigned char *pos,*buf;
1611
names=uint2korr(head+8);
1612
a_length=(names+2)*sizeof(char *); /* Room for two extra */
1617
save_names->type_names=0; /* Clear if error */
1621
length=uint2korr(head+4);
1622
lseek(file,64,SEEK_SET);
1623
if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
1624
my_read(file, buf+a_length, (size_t) (length+names*4),
1626
{ /* purecov: inspected */
1629
return(0L); /* purecov: inspected */
1631
pos= buf+a_length+length;
1632
ret_value=uint4korr(pos);
1637
free((unsigned char*) buf);
1640
memset(save_names, 0, sizeof(save_names));
1644
str=(char *) (buf+a_length);
1645
fix_type_pointers((const char ***) &buf,save_names,1,&str);
1652
Read string from a file with malloc
1655
We add an \0 at end of the read string to make reading of C strings easier
1658
int read_string(File file, unsigned char**to, size_t length)
1663
if (!(*to= (unsigned char*) malloc(length+1)) ||
1664
my_read(file, *to, length,MYF(MY_NABP)))
1669
return(1); /* purecov: inspected */
1671
*((char*) *to+length)= '\0';
1676
/* Add a new form to a form file */
1678
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1679
const char *newname)
1681
uint32_t i,bufflength,maxlength,n_length,length,names;
1682
off_t endpos,newpos;
1683
unsigned char buff[IO_SIZE];
1686
length=(uint32_t) strlen(newname)+1;
1687
n_length=uint2korr(fileinfo+4);
1688
maxlength=uint2korr(fileinfo+6);
1689
names=uint2korr(fileinfo+8);
1690
newpos=uint4korr(fileinfo+10);
1692
if (64+length+n_length+(names+1)*4 > maxlength)
1695
int4store(fileinfo+10,newpos);
1696
endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
1697
bufflength= (uint32_t) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */
1699
while (endpos > maxlength)
1701
lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
1702
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1704
lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
1705
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1707
endpos-=bufflength; bufflength=IO_SIZE;
1709
memset(buff, 0, IO_SIZE); /* Null new block */
1710
lseek(file,(ulong) maxlength,SEEK_SET);
1711
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1713
maxlength+=IO_SIZE; /* Fix old ref */
1714
int2store(fileinfo+6,maxlength);
1715
for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
1718
endpos=uint4korr(pos)+IO_SIZE;
1719
int4store(pos,endpos);
1726
sprintf((char*)buff,"/%s/",newname);
1729
sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
1730
lseek(file, 63 + n_length,SEEK_SET);
1731
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1732
(names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1733
names*4, MYF(MY_NABP+MY_WME))) ||
1734
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1735
return(0L); /* purecov: inspected */
1737
int2store(fileinfo+8,names+1);
1738
int2store(fileinfo+4,n_length+length);
1739
assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1741
} /* make_new_entry */
1744
/* error message when opening a form file */
1746
void open_table_error(TableShare *share, int error, int db_errno, int errarg)
1749
char buff[FN_REFLEN];
1750
myf errortype= ME_ERROR+ME_WAITTANG;
1755
if (db_errno == ENOENT)
1756
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1759
sprintf(buff,"%s",share->normalized_path.str);
1760
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1761
errortype, buff, db_errno);
1767
const char *datext= "";
1769
if (share->db_type() != NULL)
1771
if ((file= get_new_handler(share, current_session->mem_root,
1774
if (!(datext= *file->bas_ext()))
1778
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1779
ER_FILE_USED : ER_CANT_OPEN_FILE;
1780
sprintf(buff,"%s%s", share->normalized_path.str,datext);
1781
my_error(err_no,errortype, buff, db_errno);
1787
const char *csname= get_charset_name((uint32_t) errarg);
1789
if (!csname || csname[0] =='?')
1791
snprintf(tmp, sizeof(tmp), "#%d", errarg);
1794
my_printf_error(ER_UNKNOWN_COLLATION,
1795
_("Unknown collation '%s' in table '%-.64s' definition"),
1796
MYF(0), csname, share->table_name.str);
1800
sprintf(buff,"%s",share->normalized_path.str);
1801
my_printf_error(ER_NOT_FORM_FILE,
1802
_("Table '%-.64s' was created with a different version "
1803
"of Drizzle and cannot be read"),
1808
default: /* Better wrong error than none */
1810
sprintf(buff,"%s",share->normalized_path.str);
1811
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1815
} /* open_table_error */
1819
** fix a str_type to a array type
1820
** typeparts separated with some char. differents types are separated
1825
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
1828
char *type_name, *ptr;
1834
point_to_type->name=0;
1835
point_to_type->type_names= *array;
1837
if ((chr= *ptr)) /* Test if empty type */
1839
while ((type_name=strchr(ptr+1,chr)) != NULL)
1841
*((*array)++) = ptr+1;
1842
*type_name= '\0'; /* End string */
1845
ptr+=2; /* Skip end mark and last 0 */
1849
point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
1851
*((*array)++)= NULL; /* End of type */
1853
*names=ptr; /* Update end */
1855
} /* fix_type_pointers */
1858
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1860
TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
217
result->count= strings.elements;
1863
result->count=strings.elements;
219
1865
uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
221
if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
1866
if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
224
1868
result->type_lengths= (uint*) (result->type_names + result->count + 1);
226
1869
List_iterator<String> it(strings);
228
for (uint32_t i= 0; (tmp= it++); i++)
1871
for (uint32_t i=0; (tmp=it++) ; i++)
230
1873
result->type_names[i]= tmp->ptr();
231
1874
result->type_lengths[i]= tmp->length();
234
result->type_names[result->count]= 0; // End marker
1876
result->type_names[result->count]= 0; // End marker
235
1877
result->type_lengths[result->count]= 0;
2195
Checks whether a table is intact. Should be done *just* after the table has
2198
@param[in] table The table to check
2199
@param[in] table_f_count Expected number of columns in the table
2200
@param[in] table_def Expected structure of the table (column name
2204
@retval TRUE There was an error. An error message is output
2205
to the error log. We do not push an error
2206
message into the error stack because this
2207
function is currently only called at start up,
2208
and such errors never reach the user.
2212
Table::table_check_intact(const uint32_t table_f_count,
2213
const TABLE_FIELD_W_TYPE *table_def)
2217
bool fields_diff_count;
2219
fields_diff_count= (s->fields != table_f_count);
2220
if (fields_diff_count)
2223
/* previous MySQL version */
2224
if (DRIZZLE_VERSION_ID > s->mysql_version)
2226
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2227
alias, table_f_count, s->fields,
2228
s->mysql_version, DRIZZLE_VERSION_ID);
2231
else if (DRIZZLE_VERSION_ID == s->mysql_version)
2233
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2234
table_f_count, s->fields);
2238
Something has definitely changed, but we're running an older
2239
version of MySQL with new system tables.
2240
Let's check column definitions. If a column was added at
2241
the end of the table, then we don't care much since such change
2242
is backward compatible.
2245
char buffer[STRING_BUFFER_USUAL_SIZE];
2246
for (i=0 ; i < table_f_count; i++, table_def++)
2248
String sql_type(buffer, sizeof(buffer), system_charset_info);
2252
Field *cur_field= this->field[i];
2254
if (strncmp(cur_field->field_name, table_def->name.str,
2255
table_def->name.length))
2258
Name changes are not fatal, we use ordinal numbers to access columns.
2259
Still this can be a sign of a tampered table, output an error
2262
errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2263
"expected column '%s' at position %d, found '%s'."),
2264
s->db.str, alias, table_def->name.str, i,
2265
cur_field->field_name);
2267
cur_field->sql_type(sql_type);
2269
Generally, if column types don't match, then something is
2272
However, we only compare column definitions up to the
2273
length of the original definition, since we consider the
2274
following definitions compatible:
2276
1. DATETIME and DATETIM
2277
2. INT(11) and INT(11
2278
3. SET('one', 'two') and SET('one', 'two', 'more')
2280
For SETs or ENUMs, if the same prefix is there it's OK to
2281
add more elements - they will get higher ordinal numbers and
2282
the new table definition is backward compatible with the
2285
if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2286
table_def->type.length - 1))
2288
errmsg_printf(ERRMSG_LVL_ERROR,
2289
_("Incorrect definition of table %s.%s: "
2290
"expected column '%s' at position %d to have type "
2291
"%s, found type %s."),
2293
table_def->name.str, i, table_def->type.str,
2294
sql_type.c_ptr_safe());
2297
else if (table_def->cset.str && !cur_field->has_charset())
2299
errmsg_printf(ERRMSG_LVL_ERROR,
2300
_("Incorrect definition of table %s.%s: "
2301
"expected the type of column '%s' at position %d "
2302
"to have character set '%s' but the type has no "
2305
table_def->name.str, i, table_def->cset.str);
2308
else if (table_def->cset.str &&
2309
strcmp(cur_field->charset()->csname, table_def->cset.str))
2311
errmsg_printf(ERRMSG_LVL_ERROR,
2312
_("Incorrect definition of table %s.%s: "
2313
"expected the type of column '%s' at position %d "
2314
"to have character set '%s' but found "
2315
"character set '%s'."),
2317
table_def->name.str, i, table_def->cset.str,
2318
cur_field->charset()->csname);
2324
errmsg_printf(ERRMSG_LVL_ERROR,
2325
_("Incorrect definition of table %s.%s: "
2326
"expected column '%s' at position %d to have type %s "
2327
" but the column is not found."),
2329
table_def->name.str, i, table_def->type.str);
2338
Create Item_field for each column in the table.
2341
Table::fill_item_list()
2342
item_list a pointer to an empty list used to store items
2345
Create Item_field object for each column in the table and
2346
initialize it with the corresponding Field. New items are
2347
created in the current Session memory root.
2354
bool Table::fill_item_list(List<Item> *item_list) const
2357
All Item_field's created using a direct pointer to a field
2358
are fixed in Item_field constructor.
2360
for (Field **ptr= field; *ptr; ptr++)
2362
Item_field *item= new Item_field(*ptr);
2363
if (!item || item_list->push_back(item))
2370
Reset an existing list of Item_field items to point to the
2371
Fields of this table.
2374
Table::fill_item_list()
2375
item_list a non-empty list with Item_fields
2378
This is a counterpart of fill_item_list used to redirect
2379
Item_fields to the fields of a newly created table.
2380
The caller must ensure that number of items in the item_list
2381
is the same as the number of columns in the table.
2384
void Table::reset_item_list(List<Item> *item_list) const
2386
List_iterator_fast<Item> it(*item_list);
2387
for (Field **ptr= field; *ptr; ptr++)
2389
Item_field *item_field= (Item_field*) it++;
2390
assert(item_field != 0);
2391
item_field->reset_field(*ptr);
2397
Find underlying base tables (TableList) which represent given
2398
table_to_find (Table)
2401
TableList::find_underlying_table()
2402
table_to_find table to find
2405
0 table is not found
2406
found table reference
2409
TableList *TableList::find_underlying_table(Table *table_to_find)
2411
/* is this real table and table which we are looking for? */
2412
if (table == table_to_find && merge_underlying_list == 0)
2415
for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2418
if ((result= tbl->find_underlying_table(table_to_find)))
2425
cleunup items belonged to view fields translation table
2428
TableList::cleanup_items()
2431
void TableList::cleanup_items()
2436
bool TableList::placeholder()
2438
return derived || schema_table || (create && !table->getDBStat()) || !table;
2443
Set insert_values buffer
2447
mem_root memory pool for allocating
2451
TRUE - out of memory
2454
bool TableList::set_insert_values(MEM_ROOT *mem_root)
2458
if (!table->insert_values &&
2459
!(table->insert_values= (unsigned char *)alloc_root(mem_root,
2460
table->s->rec_buff_length)))
2469
Test if this is a leaf with respect to name resolution.
2472
TableList::is_leaf_for_name_resolution()
2475
A table reference is a leaf with respect to name resolution if
2476
it is either a leaf node in a nested join tree (table, view,
2477
schema table, subquery), or an inner node that represents a
2478
NATURAL/USING join, or a nested join with materialized join
2482
TRUE if a leaf, false otherwise.
2484
bool TableList::is_leaf_for_name_resolution()
2486
return (is_natural_join || is_join_columns_complete || !nested_join);
2491
Retrieve the first (left-most) leaf in a nested join tree with
2492
respect to name resolution.
2495
TableList::first_leaf_for_name_resolution()
2498
Given that 'this' is a nested table reference, recursively walk
2499
down the left-most children of 'this' until we reach a leaf
2500
table reference with respect to name resolution.
2503
The left-most child of a nested table reference is the last element
2504
in the list of children because the children are inserted in
2508
If 'this' is a nested table reference - the left-most child of
2509
the tree rooted in 'this',
2513
TableList *TableList::first_leaf_for_name_resolution()
2515
TableList *cur_table_ref= NULL;
2516
nested_join_st *cur_nested_join;
2518
if (is_leaf_for_name_resolution())
2520
assert(nested_join);
2522
for (cur_nested_join= nested_join;
2524
cur_nested_join= cur_table_ref->nested_join)
2526
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2527
cur_table_ref= it++;
2529
If the current nested join is a RIGHT JOIN, the operands in
2530
'join_list' are in reverse order, thus the first operand is
2531
already at the front of the list. Otherwise the first operand
2532
is in the end of the list of join operands.
2534
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2537
while ((next= it++))
2538
cur_table_ref= next;
2540
if (cur_table_ref->is_leaf_for_name_resolution())
2543
return cur_table_ref;
2548
Retrieve the last (right-most) leaf in a nested join tree with
2549
respect to name resolution.
2552
TableList::last_leaf_for_name_resolution()
2555
Given that 'this' is a nested table reference, recursively walk
2556
down the right-most children of 'this' until we reach a leaf
2557
table reference with respect to name resolution.
2560
The right-most child of a nested table reference is the first
2561
element in the list of children because the children are inserted
2565
- If 'this' is a nested table reference - the right-most child of
2566
the tree rooted in 'this',
2570
TableList *TableList::last_leaf_for_name_resolution()
2572
TableList *cur_table_ref= this;
2573
nested_join_st *cur_nested_join;
2575
if (is_leaf_for_name_resolution())
2577
assert(nested_join);
2579
for (cur_nested_join= nested_join;
2581
cur_nested_join= cur_table_ref->nested_join)
2583
cur_table_ref= cur_nested_join->join_list.head();
2585
If the current nested is a RIGHT JOIN, the operands in
2586
'join_list' are in reverse order, thus the last operand is in the
2589
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2591
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2593
cur_table_ref= it++;
2594
while ((next= it++))
2595
cur_table_ref= next;
2597
if (cur_table_ref->is_leaf_for_name_resolution())
2600
return cur_table_ref;
404
2604
/*****************************************************************************
405
2605
Functions to handle column usage bitmaps (read_set, write_set etc...)
406
2606
*****************************************************************************/
1398
3870
session->mem_root= mem_root_save;
3871
table->free_tmp_table(session); /* purecov: inspected */
3872
if (temp_pool_slot != BIT_NONE)
3873
temp_pool.reset(temp_pool_slot);
3874
return(NULL); /* purecov: inspected */
1404
3877
/****************************************************************************/
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;
3880
Create a reduced Table object with properly set up Field list from a
3881
list of field definitions.
3883
The created table doesn't have a table handler associated with
3884
it, has no keys, no group/distinct, no copy_funcs array.
3885
The sole purpose of this Table object is to use the power of Field
3886
class to read/write data to/from table->record[0]. Then one can store
3887
the record in any container (RB tree, hash, etc).
3888
The table is created in Session mem_root, so are the table's fields.
3889
Consequently, if you don't BLOB fields, you don't need to free it.
3891
@param session connection handle
3892
@param field_list list of column definitions
3895
0 if out of memory, Table object in case of success
3898
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
3900
uint32_t field_count= field_list.elements;
3901
uint32_t blob_count= 0;
3903
Create_field *cdef; /* column definition */
3904
uint32_t record_length= 0;
3905
uint32_t null_count= 0; /* number of columns which may be null */
3906
uint32_t null_pack_length; /* NULL representation array length */
3907
uint32_t *blob_field;
3911
if (!multi_alloc_root(session->mem_root,
3912
&table, sizeof(*table),
3913
&share, sizeof(*share),
3914
&field, (field_count + 1) * sizeof(Field*),
3915
&blob_field, (field_count+1) *sizeof(uint32_t),
3919
memset(table, 0, sizeof(*table));
3920
memset(share, 0, sizeof(*share));
3921
table->field= field;
3923
share->blob_field= blob_field;
3924
share->fields= field_count;
3925
share->blob_ptr_size= portable_sizeof_char_ptr;
3926
table->setup_tmp_table_column_bitmaps();
3928
/* Create all fields and calculate the total length of record */
3929
List_iterator_fast<Create_field> it(field_list);
3930
while ((cdef= it++))
3932
*field= make_field(share, NULL, 0, cdef->length,
3933
(unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
3934
f_maybe_null(cdef->pack_flag) ? 1 : 0,
3935
cdef->pack_flag, cdef->sql_type, cdef->charset,
3937
cdef->interval, cdef->field_name);
3940
(*field)->init(table);
3941
record_length+= (*field)->pack_length();
3942
if (! ((*field)->flags & NOT_NULL_FLAG))
3945
if ((*field)->flags & BLOB_FLAG)
3946
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
3950
*field= NULL; /* mark the end of the list */
3951
share->blob_field[blob_count]= 0; /* mark the end of the list */
3952
share->blob_fields= blob_count;
3954
null_pack_length= (null_count + 7)/8;
3955
share->reclength= record_length + null_pack_length;
3956
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3957
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
3958
if (!table->record[0])
3961
if (null_pack_length)
3963
table->null_flags= (unsigned char*) table->record[0];
3964
share->null_fields= null_count;
3965
share->null_bytes= null_pack_length;
3968
table->in_use= session; /* field->reset() may access table->in_use */
3970
/* Set up field pointers */
3971
unsigned char *null_pos= table->record[0];
3972
unsigned char *field_pos= null_pos + share->null_bytes;
3973
uint32_t null_bit= 1;
3975
for (field= table->field; *field; ++field)
3977
Field *cur_field= *field;
3978
if ((cur_field->flags & NOT_NULL_FLAG))
3979
cur_field->move_field(field_pos);
3982
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
3984
if (null_bit == (1 << 8))
3992
field_pos+= cur_field->pack_length();
3997
for (field= table->field; *field; ++field)
3998
delete *field; /* just invokes field destructor */
4003
bool Table::open_tmp_table()
4006
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4007
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4009
file->print_error(error,MYF(0)); /* purecov: inspected */
4013
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
4019
Create MyISAM temporary table
4022
create_myisam_tmp_table()
4023
keyinfo Description of the index (there is always one index)
4024
start_recinfo MyISAM's column descriptions
4025
recinfo INOUT End of MyISAM's column descriptions
4029
Create a MyISAM temporary table according to passed description. The is
4030
assumed to have one unique index or constraint.
4032
The passed array or MI_COLUMNDEF structures must have this form:
4034
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4035
when there are many nullable columns)
4037
3. One free MI_COLUMNDEF element (*recinfo points here)
4039
This function may use the free element to create hash column for unique
4047
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4048
MI_COLUMNDEF *start_recinfo,
4049
MI_COLUMNDEF **recinfo,
4054
MI_UNIQUEDEF uniquedef;
4055
TableShare *share= s;
4058
{ // Get keys for ni_create
4059
bool using_unique_constraint=0;
4060
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4061
sizeof(*seg) * keyinfo->key_parts);
4065
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4066
if (keyinfo->key_length >= file->max_key_length() ||
4067
keyinfo->key_parts > file->max_key_parts() ||
4070
/* Can't create a key; Make a unique constraint instead of a key */
4073
using_unique_constraint=1;
4074
memset(&uniquedef, 0, sizeof(uniquedef));
4075
uniquedef.keysegs=keyinfo->key_parts;
4077
uniquedef.null_are_equal=1;
4079
/* Create extra column for hash value */
4080
memset(*recinfo, 0, sizeof(**recinfo));
4081
(*recinfo)->type= FIELD_CHECK;
4082
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4084
share->reclength+=MI_UNIQUE_HASH_LENGTH;
4088
/* Create an unique key */
4089
memset(&keydef, 0, sizeof(keydef));
4090
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4091
keydef.keysegs= keyinfo->key_parts;
4094
for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4096
Field *key_field=keyinfo->key_part[i].field;
4098
seg->language= key_field->charset()->number;
4099
seg->length= keyinfo->key_part[i].length;
4100
seg->start= keyinfo->key_part[i].offset;
4101
if (key_field->flags & BLOB_FLAG)
4104
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4105
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4106
seg->bit_start= (uint8_t)(key_field->pack_length()
4107
- share->blob_ptr_size);
4108
seg->flag= HA_BLOB_PART;
4109
seg->length=0; // Whole blob in unique constraint
4113
seg->type= keyinfo->key_part[i].type;
4115
if (!(key_field->flags & NOT_NULL_FLAG))
4117
seg->null_bit= key_field->null_bit;
4118
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4120
We are using a GROUP BY on something that contains NULL
4121
In this case we have to tell MyISAM that two NULL should
4122
on INSERT be regarded at the same value
4124
if (!using_unique_constraint)
4125
keydef.flag|= HA_NULL_ARE_EQUAL;
4129
MI_CREATE_INFO create_info;
4130
memset(&create_info, 0, sizeof(create_info));
4132
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4134
create_info.data_file_length= ~(uint64_t) 0;
4136
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4137
(uint32_t) (*recinfo-start_recinfo),
4139
share->uniques, &uniquedef,
4141
HA_CREATE_TMP_TABLE)))
4143
file->print_error(error,MYF(0)); /* purecov: inspected */
4147
status_var_increment(in_use->status_var.created_tmp_disk_tables);
4148
share->db_record_offset= 1;
4155
void Table::free_tmp_table(Session *session)
4157
MEM_ROOT own_root= mem_root;
4158
const char *save_proc_info;
4160
save_proc_info=session->get_proc_info();
4161
session->set_proc_info("removing tmp table");
4163
// Release latches since this can take a long time
4164
ha_release_temporary_latches(session);
4169
file->ha_drop_table(s->table_name.str);
4171
file->ha_delete_table(s->table_name.str);
4176
for (Field **ptr= field ; *ptr ; ptr++)
4178
free_io_cache(this);
4180
if (temp_pool_slot != BIT_NONE)
4181
temp_pool.reset(temp_pool_slot);
4183
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4184
session->set_proc_info(save_proc_info);
4190
If a HEAP table gets full, create a MyISAM table and copy all rows
4194
bool create_myisam_from_heap(Session *session, Table *table,
4195
MI_COLUMNDEF *start_recinfo,
4196
MI_COLUMNDEF **recinfo,
4197
int error, bool ignore_last_dupp_key_error)
4201
const char *save_proc_info;
4204
if (table->s->db_type() != heap_engine ||
4205
error != HA_ERR_RECORD_FILE_FULL)
4207
table->file->print_error(error,MYF(0));
4211
// Release latches since this can take a long time
4212
ha_release_temporary_latches(session);
4216
new_table.s= &share;
4217
new_table.s->storage_engine= myisam_engine;
4218
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4219
new_table.s->db_type())))
4220
return(1); // End of memory
4222
save_proc_info=session->get_proc_info();
4223
session->set_proc_info("converting HEAP to MyISAM");
4225
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4226
recinfo, session->lex->select_lex.options |
4229
if (new_table.open_tmp_table())
4231
if (table->file->indexes_are_disabled())
4232
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4233
table->file->ha_index_or_rnd_end();
4234
table->file->ha_rnd_init(1);
4237
new_table.file->extra(HA_EXTRA_NO_ROWS);
4238
new_table.no_rows=1;
4241
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4242
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4245
copy all old rows from heap table to MyISAM table
4246
This is the only code that uses record[1] to read/write but this
4247
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4249
while (!table->file->rnd_next(new_table.record[1]))
4251
write_err= new_table.file->ha_write_row(new_table.record[1]);
4255
/* copy row that filled HEAP table */
4256
if ((write_err=new_table.file->ha_write_row(table->record[0])))
4258
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4259
!ignore_last_dupp_key_error)
4263
/* remove heap table and change to use myisam table */
4264
(void) table->file->ha_rnd_end();
4265
(void) table->file->close(); // This deletes the table !
4268
new_table.s= table->s; // Keep old share
4272
table->file->change_table_ptr(table, table->s);
4273
table->use_all_columns();
4276
const char *new_proc_info=
4277
(!strcmp(save_proc_info,"Copying to tmp table") ?
4278
"Copying to tmp table on disk" : save_proc_info);
4279
session->set_proc_info(new_proc_info);
4284
table->file->print_error(write_err, MYF(0));
4285
(void) table->file->ha_rnd_end();
4286
(void) new_table.file->close();
4288
new_table.file->ha_delete_table(new_table.s->table_name.str);
4290
delete new_table.file;
4291
session->set_proc_info(save_proc_info);
4292
table->mem_root= new_table.mem_root;
4296
bitset<MAX_FIELDS> *Table::use_all_columns(bitset<MAX_FIELDS> *bitmap)
4298
bitset<MAX_FIELDS> *old= bitmap;
4299
bitmap= &s->all_set;
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4303
void Table::restore_column_map(bitset<MAX_FIELDS> *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
1436
4308
uint32_t Table::find_shortest_key(const key_map *usable_keys)