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>
28
#include <drizzled/virtual_column_info.h>
36
29
#include <drizzled/table_list.h>
37
30
#include <drizzled/session.h>
38
31
#include <drizzled/sql_base.h>
39
#include <drizzled/sql_select.h>
40
32
#include <drizzled/field/blob.h>
41
33
#include <drizzled/field/varstring.h>
42
34
#include <drizzled/field/double.h>
43
37
#include <drizzled/unireg.h>
44
#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"
38
#include <drizzled/serialize/table.pb.h>
50
40
#include <drizzled/item/string.h>
51
41
#include <drizzled/item/int.h>
52
42
#include <drizzled/item/decimal.h>
53
43
#include <drizzled/item/float.h>
54
44
#include <drizzled/item/null.h>
55
#include <drizzled/temporal.h>
57
#include "drizzled/table/instance.h"
59
#include "drizzled/table_proto.h"
61
47
using namespace std;
66
extern pid_t current_pid;
67
extern plugin::StorageEngine *heap_engine;
68
extern plugin::StorageEngine *myisam_engine;
70
/* Functions defined in this cursor */
72
void open_table_error(TableShare *share, int error, int db_errno,
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(TABLE_SHARE *share, int error, int db_errno,
73
55
myf errortype, int errarg);
56
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
57
uint32_t types, char **names);
75
59
/*************************************************************************/
77
// @note this should all be the destructor
78
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, reg_ext))
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 TABLE_SHARE 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
TABLE_SHARE *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;
162
This constant is used to mark that no table map version has been
163
assigned. No arithmetic is done on the value: it will be
164
overwritten with a value taken from DRIZZLE_BIN_LOG.
166
share->table_map_version= UINT64_MAX;
169
Since alloc_table_share() can be called without any locking (for
170
example, ha_create_table... functions), we do not assign a table
171
map id here. Instead we assign a value that is not used
172
elsewhere, and then assign a table map id inside open_table()
173
under the protection of the LOCK_open mutex.
175
share->table_map_id= UINT32_MAX;
176
share->cached_row_logging_check= -1;
178
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
179
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
180
pthread_cond_init(&share->cond, NULL);
187
Initialize share for temporary tables
190
init_tmp_table_share()
191
session thread handle
193
key Table_cache_key, as generated from create_table_def_key.
194
must start with db name.
195
key_length Length of key
196
table_name Table name
197
path Path to file (possible in lower case) without .frm
200
This is different from alloc_table_share() because temporary tables
201
don't have to be shared between threads or put into the table def
202
cache, so we can do some things notable simpler and faster
204
If table is not put in session->temporary_tables (happens only when
205
one uses OPEN TEMPORARY) then one can specify 'db' as key and
206
use key_length= 0 as neither table_cache_key or key_length will be used).
209
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
210
uint32_t key_length, const char *table_name,
214
memset(share, 0, sizeof(*share));
215
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
216
share->table_category= TABLE_CATEGORY_TEMPORARY;
217
share->tmp_table= INTERNAL_TMP_TABLE;
218
share->db.str= (char*) key;
219
share->db.length= strlen(key);
220
share->table_cache_key.str= (char*) key;
221
share->table_cache_key.length= key_length;
222
share->table_name.str= (char*) table_name;
223
share->table_name.length= strlen(table_name);
224
share->path.str= (char*) path;
225
share->normalized_path.str= (char*) path;
226
share->path.length= share->normalized_path.length= strlen(path);
229
Temporary tables are not replicated, but we set up these fields
230
anyway to be able to catch errors.
232
share->table_map_version= ~(uint64_t)0;
233
share->cached_row_logging_check= -1;
236
table_map_id is also used for MERGE tables to suppress repeated
237
compatibility checks.
239
share->table_map_id= (ulong) session->query_id;
246
Free table share and memory used by it
253
share->mutex must be locked when we come here if it's not a temp table
256
void free_table_share(TABLE_SHARE *share)
259
assert(share->ref_count == 0);
262
If someone is waiting for this to be deleted, inform it about this.
263
Don't do a delete until we know that no one is refering to this anymore.
265
if (share->tmp_table == NO_TMP_TABLE)
267
/* share->mutex is locked in release_table_share() */
268
while (share->waiting_on_cond)
270
pthread_cond_broadcast(&share->cond);
271
pthread_cond_wait(&share->cond, &share->mutex);
273
/* No thread refers to this anymore */
274
pthread_mutex_unlock(&share->mutex);
275
pthread_mutex_destroy(&share->mutex);
276
pthread_cond_destroy(&share->cond);
278
hash_free(&share->name_hash);
280
plugin_unlock(NULL, share->db_plugin);
281
share->db_plugin= NULL;
283
/* We must copy mem_root from share because share is allocated through it */
284
memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
285
free_root(&mem_root, MYF(0)); // Free's share
289
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
291
enum_field_types field_type;
293
switch(proto_field_type)
295
case drizzle::Table::Field::TINYINT:
296
field_type= DRIZZLE_TYPE_TINY;
298
case drizzle::Table::Field::INTEGER:
299
field_type= DRIZZLE_TYPE_LONG;
301
case drizzle::Table::Field::DOUBLE:
302
field_type= DRIZZLE_TYPE_DOUBLE;
304
case drizzle::Table::Field::TIMESTAMP:
305
field_type= DRIZZLE_TYPE_TIMESTAMP;
307
case drizzle::Table::Field::BIGINT:
308
field_type= DRIZZLE_TYPE_LONGLONG;
310
case drizzle::Table::Field::DATETIME:
311
field_type= DRIZZLE_TYPE_DATETIME;
313
case drizzle::Table::Field::DATE:
314
field_type= DRIZZLE_TYPE_DATE;
316
case drizzle::Table::Field::VARCHAR:
317
field_type= DRIZZLE_TYPE_VARCHAR;
319
case drizzle::Table::Field::DECIMAL:
320
field_type= DRIZZLE_TYPE_NEWDECIMAL;
322
case drizzle::Table::Field::ENUM:
323
field_type= DRIZZLE_TYPE_ENUM;
325
case drizzle::Table::Field::BLOB:
326
field_type= DRIZZLE_TYPE_BLOB;
328
case drizzle::Table::Field::VIRTUAL:
329
field_type= DRIZZLE_TYPE_VIRTUAL;
332
field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
339
Item * default_value_item(enum_field_types field_type,
340
const CHARSET_INFO *charset,
341
bool default_null, string default_value,
342
string default_bin_value)
344
Item *default_item= NULL;
349
return new Item_null();
354
case DRIZZLE_TYPE_TINY:
355
case DRIZZLE_TYPE_LONG:
356
case DRIZZLE_TYPE_LONGLONG:
357
default_item= new Item_int(default_value.c_str(),
358
(int64_t) my_strtoll10(default_value.c_str(),
361
default_value.length());
363
case DRIZZLE_TYPE_DOUBLE:
364
default_item= new Item_float(default_value.c_str(), default_value.length());
366
case DRIZZLE_TYPE_NULL:
367
return new Item_null();
368
case DRIZZLE_TYPE_TIMESTAMP:
369
case DRIZZLE_TYPE_DATETIME:
370
case DRIZZLE_TYPE_DATE:
371
if(default_value.compare("NOW()")==0)
373
case DRIZZLE_TYPE_ENUM:
374
default_item= new Item_string(default_value.c_str(),
375
default_value.length(),
376
system_charset_info);
378
case DRIZZLE_TYPE_VARCHAR:
379
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
380
if(charset==&my_charset_bin)
382
default_item= new Item_string(default_bin_value.c_str(),
383
default_bin_value.length(),
388
default_item= new Item_string(default_value.c_str(),
389
default_value.length(),
390
system_charset_info);
393
case DRIZZLE_TYPE_VIRTUAL:
395
case DRIZZLE_TYPE_NEWDECIMAL:
396
default_item= new Item_decimal(default_value.c_str(),
397
default_value.length(),
398
system_charset_info);
405
int parse_table_proto(Session *session, drizzle::Table &table, TABLE_SHARE *share)
410
LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
411
strlen(table.engine().name().c_str()) };
412
share->db_plugin= ha_resolve_by_name(session, &engine_name);
415
share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
417
drizzle::Table::TableOptions table_options;
419
if(table.has_options())
420
table_options= table.options();
422
uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
424
if(table_options.has_pack_keys())
426
if(table_options.pack_keys())
427
db_create_options|= HA_OPTION_PACK_KEYS;
429
db_create_options|= HA_OPTION_NO_PACK_KEYS;
432
if(table_options.pack_record())
433
db_create_options|= HA_OPTION_PACK_RECORD;
435
if(table_options.has_checksum())
437
if(table_options.checksum())
438
db_create_options|= HA_OPTION_CHECKSUM;
440
db_create_options|= HA_OPTION_NO_CHECKSUM;
443
if(table_options.has_delay_key_write())
445
if(table_options.delay_key_write())
446
db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
448
db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
451
/* db_create_options was stored as 2 bytes in FRM
452
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
454
share->db_create_options= (db_create_options & 0x0000FFFF);
455
share->db_options_in_use= share->db_create_options;
458
share->avg_row_length= table_options.has_avg_row_length() ?
459
table_options.avg_row_length() : 0;
461
share->page_checksum= table_options.has_page_checksum() ?
462
(table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
465
share->row_type= table_options.has_row_type() ?
466
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
468
share->block_size= table_options.has_block_size() ?
469
table_options.block_size() : 0;
471
share->table_charset= get_charset(table_options.has_collation_id()?
472
table_options.collation_id() : 0);
474
if (!share->table_charset)
476
/* unknown charset in head[38] or pre-3.23 frm */
477
if (use_mb(default_charset_info))
479
/* Warn that we may be changing the size of character columns */
480
errmsg_printf(ERRMSG_LVL_WARN,
481
_("'%s' had no or invalid character set, "
482
"and default character set is multi-byte, "
483
"so character column sizes may have changed"),
486
share->table_charset= default_charset_info;
489
share->db_record_offset= 1;
491
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
493
share->db_low_byte_first= true;
495
share->max_rows= table_options.has_max_rows() ?
496
table_options.max_rows() : 0;
498
share->min_rows= table_options.has_min_rows() ?
499
table_options.min_rows() : 0;
501
share->keys= table.indexes_size();
504
for(int indx= 0; indx < table.indexes_size(); indx++)
505
share->key_parts+= table.indexes(indx).index_part_size();
507
share->key_info= (KEY*) alloc_root(&share->mem_root,
508
table.indexes_size() * sizeof(KEY)
509
+share->key_parts*sizeof(KEY_PART_INFO));
511
KEY_PART_INFO *key_part;
513
key_part= reinterpret_cast<KEY_PART_INFO*>
514
(share->key_info+table.indexes_size());
517
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
518
sizeof(ulong*)*share->key_parts);
520
share->keynames.count= table.indexes_size();
521
share->keynames.name= NULL;
522
share->keynames.type_names= (const char**)
523
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
525
share->keynames.type_lengths= (unsigned int*)
526
alloc_root(&share->mem_root,
527
sizeof(unsigned int) * (table.indexes_size()+1));
529
share->keynames.type_names[share->keynames.count]= NULL;
530
share->keynames.type_lengths[share->keynames.count]= 0;
532
KEY* keyinfo= share->key_info;
533
for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
535
drizzle::Table::Index indx= table.indexes(keynr);
541
keyinfo->flags|= HA_NOSAME;
543
if(indx.has_options())
545
drizzle::Table::Index::IndexOptions indx_options= indx.options();
546
if(indx_options.pack_key())
547
keyinfo->flags|= HA_PACK_KEY;
549
if(indx_options.var_length_key())
550
keyinfo->flags|= HA_VAR_LENGTH_PART;
552
if(indx_options.null_part_key())
553
keyinfo->flags|= HA_NULL_PART_KEY;
555
if(indx_options.binary_pack_key())
556
keyinfo->flags|= HA_BINARY_PACK_KEY;
558
if(indx_options.has_partial_segments())
559
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
561
if(indx_options.auto_generated_key())
562
keyinfo->flags|= HA_GENERATED_KEY;
564
if(indx_options.has_key_block_size())
566
keyinfo->flags|= HA_USES_BLOCK_SIZE;
567
keyinfo->block_size= indx_options.key_block_size();
571
keyinfo->block_size= 0;
578
case drizzle::Table::Index::UNKNOWN_INDEX:
579
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
581
case drizzle::Table::Index::BTREE:
582
keyinfo->algorithm= HA_KEY_ALG_BTREE;
584
case drizzle::Table::Index::RTREE:
585
keyinfo->algorithm= HA_KEY_ALG_RTREE;
587
case drizzle::Table::Index::HASH:
588
keyinfo->algorithm= HA_KEY_ALG_HASH;
590
case drizzle::Table::Index::FULLTEXT:
591
keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
594
/* TODO: suitable warning ? */
595
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
599
keyinfo->key_length= indx.key_length();
601
keyinfo->key_parts= indx.index_part_size();
603
keyinfo->key_part= key_part;
604
keyinfo->rec_per_key= rec_per_key;
606
for(unsigned int partnr= 0;
607
partnr < keyinfo->key_parts;
608
partnr++, key_part++)
610
drizzle::Table::Index::IndexPart part;
611
part= indx.index_part(partnr);
615
key_part->field= NULL;
616
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
617
key_part->null_bit= 0;
618
/* key_part->null_offset is only set if null_bit (see later) */
619
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
620
/* key_part->type ???? */
621
key_part->key_part_flag= 0;
622
if(part.has_in_reverse_order())
623
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
625
key_part->length= part.compare_length();
627
key_part->store_length= key_part->length;
629
/* key_part->offset is set later */
630
key_part->key_type= part.key_type();
634
if(!indx.has_comment())
636
keyinfo->comment.length= 0;
637
keyinfo->comment.str= NULL;
641
keyinfo->flags|= HA_USES_COMMENT;
642
keyinfo->comment.length= indx.comment().length();
643
keyinfo->comment.str= strmake_root(&share->mem_root,
644
indx.comment().c_str(),
645
keyinfo->comment.length);
648
keyinfo->name= strmake_root(&share->mem_root,
650
indx.name().length());
652
share->keynames.type_names[keynr]= keyinfo->name;
653
share->keynames.type_lengths[keynr]= indx.name().length();
656
share->keys_for_keyread.init(0);
657
share->keys_in_use.init(share->keys);
659
if(table_options.has_connect_string())
661
size_t len= table_options.connect_string().length();
662
const char* str= table_options.connect_string().c_str();
664
share->connect_string.length= len;
665
share->connect_string.str= strmake_root(&share->mem_root, str, len);
668
if(table_options.has_comment())
670
size_t len= table_options.comment().length();
671
const char* str= table_options.comment().c_str();
673
share->comment.length= len;
674
share->comment.str= strmake_root(&share->mem_root, str, len);
677
share->key_block_size= table_options.has_key_block_size() ?
678
table_options.key_block_size() : 0;
680
share->fields= table.field_size();
682
share->stored_fields= share->fields;
684
share->field= (Field**) alloc_root(&share->mem_root,
685
((share->fields+1) * sizeof(Field*)));
686
share->field[share->fields]= NULL;
688
uint32_t null_fields= 0;
691
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
692
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
694
assert(field_offsets && field_pack_length); // TODO: fixme
696
uint32_t interval_count= 0;
697
uint32_t interval_parts= 0;
699
uint32_t stored_columns_reclength= 0;
701
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
703
drizzle::Table::Field pfield= table.field(fieldnr);
704
if(pfield.has_constraints() && pfield.constraints().is_nullable())
707
bool field_is_stored= true;
709
enum_field_types drizzle_field_type=
710
proto_field_type_to_drizzle_type(pfield.type());
712
if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
714
drizzle::Table::Field::VirtualFieldOptions field_options=
715
pfield.virtual_options();
717
drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
719
field_is_stored= field_options.physically_stored();
722
field_offsets[fieldnr]= stored_columns_reclength;
724
/* the below switch is very similar to
725
Create_field::create_length_to_internal_length in field.cc
726
(which should one day be replace by just this code)
728
switch(drizzle_field_type)
730
case DRIZZLE_TYPE_BLOB:
731
case DRIZZLE_TYPE_VARCHAR:
733
drizzle::Table::Field::StringFieldOptions field_options=
734
pfield.string_options();
736
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
737
field_options.collation_id() : 0);
740
cs= default_charset_info;
742
field_pack_length[fieldnr]=
743
calc_pack_length(drizzle_field_type,
744
field_options.length() * cs->mbmaxlen);
748
case DRIZZLE_TYPE_ENUM:
750
drizzle::Table::Field::SetFieldOptions field_options=
751
pfield.set_options();
753
field_pack_length[fieldnr]=
754
get_enum_pack_length(field_options.field_value_size());
757
interval_parts+= field_options.field_value_size();
760
case DRIZZLE_TYPE_NEWDECIMAL:
762
drizzle::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
764
field_pack_length[fieldnr]=
765
my_decimal_get_binary_size(fo.precision(), fo.scale());
769
/* Zero is okay here as length is fixed for other types. */
770
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
773
share->reclength+= field_pack_length[fieldnr];
776
stored_columns_reclength+= field_pack_length[fieldnr];
779
/* data_offset added to stored_rec_length later */
780
share->stored_rec_length= stored_columns_reclength;
782
/* fix up offsets for non-stored fields (at end of record) */
783
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
785
drizzle::Table::Field pfield= table.field(fieldnr);
787
bool field_is_stored= true;
789
enum_field_types drizzle_field_type=
790
proto_field_type_to_drizzle_type(pfield.type());
792
if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
794
drizzle::Table::Field::VirtualFieldOptions field_options=
795
pfield.virtual_options();
797
field_is_stored= field_options.physically_stored();
802
field_offsets[fieldnr]= stored_columns_reclength;
803
stored_columns_reclength+= field_pack_length[fieldnr];
806
share->null_fields= null_fields;
808
ulong null_bits= null_fields;
809
if(!table_options.pack_record())
811
ulong data_offset= (null_bits + 7)/8;
814
share->reclength+= data_offset;
815
share->stored_rec_length+= data_offset;
817
ulong rec_buff_length;
819
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
820
share->rec_buff_length= rec_buff_length;
822
unsigned char* record= NULL;
824
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
828
memset(record, 0, rec_buff_length);
832
if(!table_options.pack_record())
834
null_count++; // one bit for delete mark.
838
share->default_values= record;
842
share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
843
interval_count*sizeof(TYPELIB));
846
share->intervals= NULL;
848
share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
849
(share->fields+1)*sizeof(char*));
851
share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
852
(share->fields+1)*sizeof(unsigned int));
854
share->fieldnames.type_names[share->fields]= NULL;
855
share->fieldnames.type_lengths[share->fields]= 0;
856
share->fieldnames.count= share->fields;
859
/* Now fix the TYPELIBs for the intervals (enum values)
863
uint32_t interval_nr= 0;
865
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
867
drizzle::Table::Field pfield= table.field(fieldnr);
870
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
871
pfield.name().c_str(),
872
pfield.name().length());
874
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
877
if(pfield.type() != drizzle::Table::Field::ENUM)
880
drizzle::Table::Field::SetFieldOptions field_options=
881
pfield.set_options();
883
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
884
field_options.collation_id() : 0);
887
charset= default_charset_info;
889
TYPELIB *t= &(share->intervals[interval_nr]);
891
t->type_names= (const char**)alloc_root(&share->mem_root,
892
(field_options.field_value_size()+1)*sizeof(char*));
894
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
895
(field_options.field_value_size()+1)*sizeof(unsigned int));
897
t->type_names[field_options.field_value_size()]= NULL;
898
t->type_lengths[field_options.field_value_size()]= 0;
900
t->count= field_options.field_value_size();
903
for(int n=0; n < field_options.field_value_size(); n++)
905
t->type_names[n]= strmake_root(&share->mem_root,
906
field_options.field_value(n).c_str(),
907
field_options.field_value(n).length());
909
/* Go ask the charset what the length is as for "" length=1
910
and there's stripping spaces or some other crack going on.
913
lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
914
field_options.field_value(n).length());
915
t->type_lengths[n]= lengthsp;
921
/* and read the fields */
924
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
927
use_hash= !hash_init(&share->name_hash,
930
(hash_get_key) get_field_name, 0, 0);
932
unsigned char* null_pos= record;;
933
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
935
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
937
drizzle::Table::Field pfield= table.field(fieldnr);
939
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
941
switch(pfield.format())
943
case drizzle::Table::Field::DefaultFormat:
944
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
946
case drizzle::Table::Field::FixedFormat:
947
column_format= COLUMN_FORMAT_TYPE_FIXED;
949
case drizzle::Table::Field::DynamicFormat:
950
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
956
Field::utype unireg_type= Field::NONE;
958
if(pfield.has_numeric_options()
959
&& pfield.numeric_options().is_autoincrement())
961
unireg_type= Field::NEXT_NUMBER;
964
if(pfield.has_options()
965
&& pfield.options().has_default_value()
966
&& pfield.options().default_value().compare("NOW()")==0)
968
if(pfield.options().has_update_value()
969
&& pfield.options().update_value().compare("NOW()")==0)
971
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
973
else if (!pfield.options().has_update_value())
975
unireg_type= Field::TIMESTAMP_DN_FIELD;
978
assert(1); // Invalid update value.
980
else if (pfield.has_options()
981
&& pfield.options().has_update_value()
982
&& pfield.options().update_value().compare("NOW()")==0)
984
unireg_type= Field::TIMESTAMP_UN_FIELD;
988
if(!pfield.has_comment())
990
comment.str= (char*)"";
995
size_t len= pfield.comment().length();
996
const char* str= pfield.comment().c_str();
998
comment.str= strmake_root(&share->mem_root, str, len);
1002
enum_field_types field_type;
1003
virtual_column_info *vcol_info= NULL;
1004
bool field_is_stored= true;
1007
field_type= proto_field_type_to_drizzle_type(pfield.type());
1009
if(field_type==DRIZZLE_TYPE_VIRTUAL)
1011
drizzle::Table::Field::VirtualFieldOptions field_options=
1012
pfield.virtual_options();
1014
vcol_info= new virtual_column_info();
1015
field_type= proto_field_type_to_drizzle_type(field_options.type());
1016
field_is_stored= field_options.physically_stored();
1018
size_t len= field_options.expression().length();
1019
const char* str= field_options.expression().c_str();
1021
vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
1022
vcol_info->expr_str.length= len;
1027
const CHARSET_INFO *charset= &my_charset_bin;
1029
if(field_type==DRIZZLE_TYPE_BLOB
1030
|| field_type==DRIZZLE_TYPE_VARCHAR)
1032
drizzle::Table::Field::StringFieldOptions field_options=
1033
pfield.string_options();
1035
charset= get_charset(field_options.has_collation_id()?
1036
field_options.collation_id() : 0);
1039
charset= default_charset_info;
1043
if(field_type==DRIZZLE_TYPE_ENUM)
1045
drizzle::Table::Field::SetFieldOptions field_options=
1046
pfield.set_options();
1048
charset= get_charset(field_options.has_collation_id()?
1049
field_options.collation_id() : 0);
1052
charset= default_charset_info;
1056
Item *default_value= NULL;
1058
if(pfield.options().has_default_value()
1059
|| pfield.options().has_default_null()
1060
|| pfield.options().has_default_bin_value())
1062
default_value= default_value_item(field_type,
1064
pfield.options().default_null(),
1065
pfield.options().default_value(),
1066
pfield.options().default_bin_value());
1069
uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
1071
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
1072
memset(&temp_table, 0, sizeof(temp_table));
1073
temp_table.s= share;
1074
temp_table.in_use= session;
1075
temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
1076
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
1078
Field* f= make_field(share, &share->mem_root,
1079
record+field_offsets[fieldnr]+data_offset,
1080
pfield.options().length(),
1086
(Field::utype) MTYP_TYPENR(unireg_type),
1087
((field_type==DRIZZLE_TYPE_ENUM)?
1088
share->intervals+(interval_nr++)
1090
share->fieldnames.type_names[fieldnr]);
1092
share->field[fieldnr]= f;
1094
f->init(&temp_table); /* blob default values need table obj */
1096
if(!(f->flags & NOT_NULL_FLAG))
1098
*f->null_ptr|= f->null_bit;
1099
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
1106
int res= default_value->save_in_field(f, 1);
1107
(void)res; // TODO error handle;
1109
else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
1110
(f->flags & NOT_NULL_FLAG))
1113
f->store((int64_t) 1, true);
1118
/* hack to undo f->init() */
1120
f->orig_table= NULL;
1122
f->field_index= fieldnr;
1123
f->comment= comment;
1124
f->vcol_info= vcol_info;
1125
f->is_stored= field_is_stored;
1127
&& !(f->unireg_check==Field::NEXT_NUMBER)
1128
&& (f->flags & NOT_NULL_FLAG)
1129
&& (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
1130
f->flags|= NO_DEFAULT_VALUE_FLAG;
1132
if(f->unireg_check == Field::NEXT_NUMBER)
1133
share->found_next_number_field= &(share->field[fieldnr]);
1135
if(share->timestamp_field == f)
1136
share->timestamp_field_offset= fieldnr;
1138
if (use_hash) /* supposedly this never fails... but comments lie */
1139
(void) my_hash_insert(&share->name_hash,
1140
(unsigned char*)&(share->field[fieldnr]));
1144
share->stored_fields--;
1148
keyinfo= share->key_info;
1149
for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
1151
key_part= keyinfo->key_part;
1153
for(unsigned int partnr= 0;
1154
partnr < keyinfo->key_parts;
1155
partnr++, key_part++)
1157
/* Fix up key_part->offset by adding data_offset.
1158
We really should compute offset as well.
1159
But at least this way we are a little better. */
1160
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1165
We need to set the unused bits to 1. If the number of bits is a multiple
1166
of 8 there are no unused bits.
1170
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1172
share->null_bytes= (null_pos - (unsigned char*) record +
1173
(null_bit_pos + 7) / 8);
1175
share->last_null_bit_pos= null_bit_pos;
1177
free(field_offsets);
1178
free(field_pack_length);
1180
handler *handler_file;
1182
if(!(handler_file= get_new_handler(share, session->mem_root,
1187
if (share->key_parts)
1189
uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
1190
&share->keynames, 3) - 1);
1192
int64_t ha_option= handler_file->ha_table_flags();
1194
keyinfo= share->key_info;
1195
key_part= keyinfo->key_part;
1197
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1199
uint32_t usable_parts= 0;
1201
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1204
If the UNIQUE key doesn't have NULL columns and is not a part key
1205
declare this as a primary key.
1208
for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
1210
uint32_t fieldnr= key_part[i].fieldnr;
1212
share->field[fieldnr-1]->null_ptr ||
1213
share->field[fieldnr-1]->key_length() !=
1216
primary_key=MAX_KEY; // Can't be used
1222
for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1225
if (!key_part->fieldnr)
1227
// error= 4; // Wrong file
1228
abort(); // goto err;
1230
field= key_part->field= share->field[key_part->fieldnr-1];
1231
key_part->type= field->key_type();
1232
if (field->null_ptr)
1234
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1235
share->default_values);
1236
key_part->null_bit= field->null_bit;
1237
key_part->store_length+=HA_KEY_NULL_LENGTH;
1238
keyinfo->flags|=HA_NULL_PART_KEY;
1239
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1240
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1242
if (field->type() == DRIZZLE_TYPE_BLOB ||
1243
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1245
if (field->type() == DRIZZLE_TYPE_BLOB)
1246
key_part->key_part_flag|= HA_BLOB_PART;
1248
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1249
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1250
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1251
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1253
if (i == 0 && key != primary_key)
1254
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1255
(keyinfo->key_parts == 1)) ?
1256
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1258
field->key_start.set_bit(key);
1259
if (field->key_length() == key_part->length &&
1260
!(field->flags & BLOB_FLAG))
1262
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1264
share->keys_for_keyread.set_bit(key);
1265
field->part_of_key.set_bit(key);
1266
field->part_of_key_not_clustered.set_bit(key);
1268
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1269
field->part_of_sortkey.set_bit(key);
1271
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1273
usable_parts++; // For FILESORT
1274
field->flags|= PART_KEY_FLAG;
1275
if (key == primary_key)
1277
field->flags|= PRI_KEY_FLAG;
1279
If this field is part of the primary key and all keys contains
1280
the primary key, then we can use any key to find this column
1282
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1284
field->part_of_key= share->keys_in_use;
1285
if (field->part_of_sortkey.is_set(key))
1286
field->part_of_sortkey= share->keys_in_use;
1289
if (field->key_length() != key_part->length)
1291
key_part->key_part_flag|= HA_PART_KEY_SEG;
1294
keyinfo->usable_key_parts= usable_parts; // Filesort
1296
set_if_bigger(share->max_key_length,keyinfo->key_length+
1297
keyinfo->key_parts);
1298
share->total_key_length+= keyinfo->key_length;
1300
MERGE tables do not have unique indexes. But every key could be
1301
an unique index on the underlying MyISAM table. (Bug #10400)
1303
if ((keyinfo->flags & HA_NOSAME) ||
1304
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1305
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1307
if (primary_key < MAX_KEY &&
1308
(share->keys_in_use.is_set(primary_key)))
1310
share->primary_key= primary_key;
1312
If we are using an integer as the primary key then allow the user to
1313
refer to it as '_rowid'
1315
if (share->key_info[primary_key].key_parts == 1)
1317
Field *field= share->key_info[primary_key].key_part[0].field;
1318
if (field && field->result_type() == INT_RESULT)
1320
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1321
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1328
share->primary_key = MAX_KEY; // we do not have a primary key
1331
share->primary_key= MAX_KEY;
1333
if (share->found_next_number_field)
1335
Field *reg_field= *share->found_next_number_field;
1336
if ((int) (share->next_number_index= (uint32_t)
1337
find_ref_key(share->key_info, share->keys,
1338
share->default_values, reg_field,
1339
&share->next_number_key_offset,
1340
&share->next_number_keypart)) < 0)
1342
/* Wrong field definition */
1347
reg_field->flags |= AUTO_INCREMENT_FLAG;
1350
if (share->blob_fields)
1355
/* Store offsets to blob fields to find them fast */
1356
if (!(share->blob_field= save=
1357
(uint*) alloc_root(&share->mem_root,
1358
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1360
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1362
if ((*ptr)->flags & BLOB_FLAG)
1367
share->db_low_byte_first= handler_file->low_byte_first();
1368
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1370
my_bitmap_map *bitmaps;
1372
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1373
share->column_bitmap_size)))
1375
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1376
bitmap_set_all(&share->all_set);
1378
delete handler_file;
1382
share->error= error;
1383
share->open_errno= my_errno;
1385
hash_free(&share->name_hash);
1386
delete handler_file;
1387
open_table_error(share, error, share->open_errno, 0);
1392
Read table definition from a binary / text based .frm file
1396
session Thread handler
1397
share Fill this with table definition
1398
db_flags Bit mask of the following flags: OPEN_VIEW
1401
This function is called when the table definition is not cached in
1403
The data is returned in 'share', which is alloced by
1404
alloc_table_share().. The code assumes that share is initialized.
1408
1 Error (see open_table_error)
1409
2 Error (see open_table_error)
1410
3 Wrong data in .frm file
1411
4 Error (see open_table_error)
1412
5 Error (see open_table_error: charset unavailable)
1413
6 Unknown .frm version
1416
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
1425
path.reserve(FN_REFLEN);
1426
path.append(share->normalized_path.str);
1427
string proto_path= path;
1429
path.append(reg_ext);
1431
proto_path.append(".dfe");
1433
drizzle::Table table;
1435
if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
1444
if(!table.IsInitialized())
1452
parse_table_proto(session, table, share);
1454
share->table_category= get_table_category(& share->db, & share->table_name);
1457
session->status_var.opened_shares++;
1460
if (error && !error_given)
1462
share->error= error;
1463
open_table_error(share, error, (share->open_errno= my_errno), 0);
1470
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1471
This routine is used for error handling purposes.
1475
table Table object for which virtual columns are set-up
1480
static void clear_field_flag(Table *table)
1484
for (ptr= table->field; *ptr; ptr++)
1485
(*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1489
The function uses the feature in fix_fields where the flag
1490
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1491
This field must always be reset before returning from the function
1492
since it is used for other purposes as well.
1495
fix_fields_vcol_func()
1496
session The thread object
1497
func_item The item tree reference of the virtual columnfunction
1498
table The table object
1499
field_name The name of the processed field
1502
true An error occurred, something was wrong with the
1504
false Ok, a partition field array was created
1507
bool fix_fields_vcol_func(Session *session,
1510
const char *field_name)
1512
uint32_t dir_length, home_dir_length;
1515
TableList *save_table_list, *save_first_table, *save_last_table;
1517
Name_resolution_context *context;
1518
const char *save_where;
1520
char db_name_string[FN_REFLEN];
1521
bool save_use_only_table_context;
1522
Field **ptr, *field;
1523
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1527
Set-up the TABLE_LIST object to be a list with a single table
1528
Set the object to zero to create NULL pointers and set alias
1529
and real name to table name and get database name from file name.
1532
bzero((void*)&tables, sizeof(TableList));
1533
tables.alias= tables.table_name= (char*) table->s->table_name.str;
1534
tables.table= table;
1535
tables.next_local= NULL;
1536
tables.next_name_resolution_table= NULL;
1537
memcpy(db_name_string,
1538
table->s->normalized_path.str,
1539
table->s->normalized_path.length);
1540
db_name_string[table->s->normalized_path.length]= '\0';
1541
dir_length= dirname_length(db_name_string);
1542
db_name_string[dir_length - 1]= 0;
1543
home_dir_length= dirname_length(db_name_string);
1544
db_name= &db_name_string[home_dir_length];
1547
session->mark_used_columns= MARK_COLUMNS_NONE;
1549
context= session->lex->current_context();
1550
table->map= 1; //To ensure correct calculation of const item
1551
table->get_fields_in_item_tree= true;
1552
save_table_list= context->table_list;
1553
save_first_table= context->first_name_resolution_table;
1554
save_last_table= context->last_name_resolution_table;
1555
context->table_list= &tables;
1556
context->first_name_resolution_table= &tables;
1557
context->last_name_resolution_table= NULL;
1558
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1559
save_where= session->where;
1560
session->where= "virtual column function";
1562
/* Save the context before fixing the fields*/
1563
save_use_only_table_context= session->lex->use_only_table_context;
1564
session->lex->use_only_table_context= true;
1565
/* Fix fields referenced to by the virtual column function */
1566
error= func_expr->fix_fields(session, (Item**)0);
1567
/* Restore the original context*/
1568
session->lex->use_only_table_context= save_use_only_table_context;
1569
context->table_list= save_table_list;
1570
context->first_name_resolution_table= save_first_table;
1571
context->last_name_resolution_table= save_last_table;
1573
if (unlikely(error))
1575
clear_field_flag(table);
1578
session->where= save_where;
1580
Walk through the Item tree checking if all items are valid
1581
to be part of the virtual column
1583
error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1586
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1587
clear_field_flag(table);
1590
if (unlikely(func_expr->const_item()))
1592
my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1593
clear_field_flag(table);
1596
/* Ensure that this virtual column is not based on another virtual field. */
1598
while ((field= *(ptr++)))
1600
if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1603
my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1604
clear_field_flag(table);
1609
Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1610
when calling fix_fields.
1612
clear_field_flag(table);
1616
table->get_fields_in_item_tree= false;
1617
session->mark_used_columns= save_mark_used_columns;
1618
table->map= 0; //Restore old value
1623
Unpack the definition of a virtual column
1626
unpack_vcol_info_from_frm()
1627
session Thread handler
1628
table Table with the checked field
1629
field Pointer to Field object
1630
open_mode Open table mode needed to determine
1631
which errors need to be generated in a failure
1632
error_reported updated flag for the caller that no other error
1633
messages are to be generated.
1639
bool unpack_vcol_info_from_frm(Session *session,
1642
LEX_STRING *vcol_expr,
1643
open_table_mode open_mode,
1644
bool *error_reported)
1649
Step 1: Construct a statement for the parser.
1650
The parsed string needs to take the following format:
1651
"PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1653
char *vcol_expr_str;
1656
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1658
parse_vcol_keyword.length + 3)))
1662
memcpy(vcol_expr_str,
1663
(char*) parse_vcol_keyword.str,
1664
parse_vcol_keyword.length);
1665
str_len= parse_vcol_keyword.length;
1666
memcpy(vcol_expr_str + str_len, "(", 1);
1668
memcpy(vcol_expr_str + str_len,
1669
(char*) vcol_expr->str,
1671
str_len+= vcol_expr->length;
1672
memcpy(vcol_expr_str + str_len, ")", 1);
1674
memcpy(vcol_expr_str + str_len, "\0", 1);
1676
Lex_input_stream lip(session, vcol_expr_str, str_len);
1679
Step 2: Setup session for parsing.
1680
1) make Item objects be created in the memory allocated for the Table
1681
object (not TABLE_SHARE)
1682
2) ensure that created Item's are not put on to session->free_list
1683
(which is associated with the parsed statement and hence cleared after
1685
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1686
to be parsed as a SQL command.
1688
MEM_ROOT **root_ptr, *old_root;
1689
Item *backup_free_list= session->free_list;
1690
root_ptr= current_mem_root_ptr();
1691
old_root= *root_ptr;
1692
*root_ptr= &table->mem_root;
1693
session->free_list= NULL;
1694
session->lex->parse_vcol_expr= true;
1697
Step 3: Use the parser to build an Item object from.
1699
if (parse_sql(session, &lip))
1703
/* From now on use vcol_info generated by the parser. */
1704
field->vcol_info= session->lex->vcol_info;
1706
/* Validate the Item tree. */
1707
if (fix_fields_vcol_func(session,
1708
field->vcol_info->expr_item,
1712
if (open_mode == OTM_CREATE)
1715
During CREATE/ALTER TABLE it is ok to receive errors here.
1716
It is not ok if it happens during the opening of an frm
1717
file as part of a normal query.
1719
*error_reported= true;
1721
field->vcol_info= NULL;
1724
field->vcol_info->item_free_list= session->free_list;
1725
session->free_list= backup_free_list;
1726
*root_ptr= old_root;
1731
session->lex->parse_vcol_expr= false;
1732
session->free_items();
1733
*root_ptr= old_root;
1734
session->free_list= backup_free_list;
1740
Open a table based on a TABLE_SHARE
1743
open_table_from_share()
1744
session Thread handler
1745
share Table definition
1746
alias Alias for table
1747
db_stat open flags (for example HA_OPEN_KEYFILE|
1748
HA_OPEN_RNDFILE..) can be 0 (example in
1750
prgflag READ_ALL etc..
1751
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1752
outparam result table
1753
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1754
if OTM_CREATE some errors are ignore
1755
if OTM_ALTER HA_OPEN is not called
1759
1 Error (see open_table_error)
1760
2 Error (see open_table_error)
1761
3 Wrong data in .frm file
1762
4 Error (see open_table_error)
1763
5 Error (see open_table_error: charset unavailable)
1764
7 Table definition has changed in engine
1767
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1768
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1769
Table *outparam, open_table_mode open_mode)
1772
uint32_t records, i, bitmap_size;
1773
bool error_reported= false;
1774
unsigned char *record, *bitmaps;
1775
Field **field_ptr, **vfield_ptr;
1777
/* Parsing of partitioning information from .frm needs session->lex set up. */
1778
assert(session->lex->is_lex_started);
1781
memset(outparam, 0, sizeof(*outparam));
1782
outparam->in_use= session;
1784
outparam->db_stat= db_stat;
1785
outparam->write_row_record= NULL;
1787
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1789
if (!(outparam->alias= strdup(alias)))
1791
outparam->quick_keys.init();
1792
outparam->covering_keys.init();
1793
outparam->keys_in_use_for_query.init();
1795
/* Allocate handler */
1797
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1799
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1809
outparam->reginfo.lock_type= TL_UNLOCK;
1810
outparam->current_lock= F_UNLCK;
1812
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1814
if (prgflag & (READ_ALL+EXTRA_RECORD))
1817
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1818
share->rec_buff_length * records)))
1819
goto err; /* purecov: inspected */
1823
/* We are probably in hard repair, and the buffers should not be used */
1824
outparam->record[0]= outparam->record[1]= share->default_values;
1828
outparam->record[0]= record;
1830
outparam->record[1]= record+ share->rec_buff_length;
1832
outparam->record[1]= outparam->record[0]; // Safety
1837
We need this because when we read var-length rows, we are not updating
1838
bytes after end of varchar
1842
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1843
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1845
memcpy(outparam->record[1], share->default_values,
1846
share->rec_buff_length);
1850
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1851
(uint32_t) ((share->fields+1)*
1853
goto err; /* purecov: inspected */
1855
outparam->field= field_ptr;
1857
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1859
outparam->null_flags= (unsigned char*) record+1;
1861
/* Setup copy of fields from share, but use the right alias and record */
1862
for (i=0 ; i < share->fields; i++, field_ptr++)
1864
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1867
(*field_ptr)= 0; // End marker
1869
if (share->found_next_number_field)
1870
outparam->found_next_number_field=
1871
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1872
if (share->timestamp_field)
1873
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1876
/* Fix key->name and key_part->field */
1877
if (share->key_parts)
1879
KEY *key_info, *key_info_end;
1880
KEY_PART_INFO *key_part;
1882
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1883
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1885
outparam->key_info= key_info;
1886
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1888
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1889
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1892
for (key_info_end= key_info + share->keys ;
1893
key_info < key_info_end ;
1896
KEY_PART_INFO *key_part_end;
1898
key_info->table= outparam;
1899
key_info->key_part= key_part;
1901
for (key_part_end= key_part+ key_info->key_parts ;
1902
key_part < key_part_end ;
1905
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1907
if (field->key_length() != key_part->length &&
1908
!(field->flags & BLOB_FLAG))
1911
We are using only a prefix of the column as a key:
1912
Create a new field for the key part that matches the index
1914
field= key_part->field=field->new_field(&outparam->mem_root,
1916
field->field_length= key_part->length;
1923
Process virtual columns, if any.
1925
if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
1926
(uint32_t) ((share->vfields+1)*
1930
outparam->vfield= vfield_ptr;
1932
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
1934
if ((*field_ptr)->vcol_info)
1936
if (unpack_vcol_info_from_frm(session,
1939
&(*field_ptr)->vcol_info->expr_str,
1943
error= 4; // in case no error is reported
1946
*(vfield_ptr++)= *field_ptr;
1949
*vfield_ptr= NULL; // End marker
1950
/* Check virtual columns against table's storage engine. */
1951
if ((share->vfields && outparam->file) &&
1952
(not outparam->file->check_if_supported_virtual_columns()))
1954
my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
1956
"Specified storage engine");
1957
error_reported= true;
1961
/* Allocate bitmaps */
1963
bitmap_size= share->column_bitmap_size;
1964
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1966
bitmap_init(&outparam->def_read_set,
1967
(my_bitmap_map*) bitmaps, share->fields, false);
1968
bitmap_init(&outparam->def_write_set,
1969
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1970
bitmap_init(&outparam->tmp_set,
1971
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1972
outparam->default_column_bitmaps();
1974
/* The table struct is now initialized; Open the table */
1976
if (db_stat && open_mode != OTM_ALTER)
1979
if ((ha_err= (outparam->file->
1980
ha_open(outparam, share->normalized_path.str,
1981
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1982
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1983
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1984
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1985
HA_OPEN_ABORT_IF_LOCKED :
1986
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1988
/* Set a flag if the table is crashed and it can be auto. repaired */
1989
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1990
outparam->file->auto_repair() &&
1991
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1995
case HA_ERR_NO_SUCH_TABLE:
1997
The table did not exists in storage engine, use same error message
1998
as if the .frm file didn't exist
2005
Too many files opened, use same error message as if the .frm
2012
outparam->file->print_error(ha_err, MYF(0));
2013
error_reported= true;
2014
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
2018
goto err; /* purecov: inspected */
2022
#if defined(HAVE_purify)
2023
memset(bitmaps, 0, bitmap_size*3);
2026
outparam->no_replicate= outparam->file;
2027
session->status_var.opened_tables++;
2032
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
2033
open_table_error(share, error, my_errno, 0);
2034
delete outparam->file;
2035
outparam->file= 0; // For easier error checking
2036
outparam->db_stat=0;
2037
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
2038
free((char*) outparam->alias);
2042
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
2043
uint32_t Table::tmpkeyval()
2045
return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
2049
Free information allocated by openfrm
2053
table Table object to free
2054
free_share Is 1 if we also want to free table_share
2057
int Table::closefrm(bool free_share)
83
error= cursor->close();
2062
error= file->close();
2063
free((char*) alias);
87
2067
for (Field **ptr=field ; *ptr ; ptr++)
94
cursor= 0; /* For easier errorchecking */
2072
file= 0; /* For easier errorchecking */
2075
if (s->tmp_table == NO_TMP_TABLE)
2076
release_table_share(s, RELEASE_NORMAL);
2078
free_table_share(s);
2080
free_root(&mem_root, MYF(0));
106
mem_root.free_root(MYF(0));
110
void Table::resetTable(Session *session,
112
uint32_t db_stat_arg)
125
db_stat= db_stat_arg;
128
record[0]= (unsigned char *) NULL;
129
record[1]= (unsigned char *) NULL;
131
insert_values.clear();
133
next_number_field= NULL;
134
found_next_number_field= NULL;
135
timestamp_field= NULL;
137
pos_in_table_list= NULL;
147
derived_select_number= 0;
148
current_lock= F_UNLCK;
162
open_placeholder= false;
163
locked_by_name= false;
166
auto_increment_field_not_null= false;
167
alias_name_used= false;
170
quick_condition_rows= 0;
172
timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
177
covering_keys.reset();
182
keys_in_use_for_query.reset();
183
keys_in_use_for_group_by.reset();
184
keys_in_use_for_order_by.reset();
186
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
187
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
189
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
190
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
192
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
197
2086
/* Deallocate temporary blob storage */
1398
4534
session->mem_root= mem_root_save;
4535
table->free_tmp_table(session); /* purecov: inspected */
4536
if (temp_pool_slot != MY_BIT_NONE)
4537
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4538
return(NULL); /* purecov: inspected */
1404
4541
/****************************************************************************/
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;
4544
Create a reduced Table object with properly set up Field list from a
4545
list of field definitions.
4547
The created table doesn't have a table handler associated with
4548
it, has no keys, no group/distinct, no copy_funcs array.
4549
The sole purpose of this Table object is to use the power of Field
4550
class to read/write data to/from table->record[0]. Then one can store
4551
the record in any container (RB tree, hash, etc).
4552
The table is created in Session mem_root, so are the table's fields.
4553
Consequently, if you don't BLOB fields, you don't need to free it.
4555
@param session connection handle
4556
@param field_list list of column definitions
4559
0 if out of memory, Table object in case of success
4562
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4564
uint32_t field_count= field_list.elements;
4565
uint32_t blob_count= 0;
4567
Create_field *cdef; /* column definition */
4568
uint32_t record_length= 0;
4569
uint32_t null_count= 0; /* number of columns which may be null */
4570
uint32_t null_pack_length; /* NULL representation array length */
4571
uint32_t *blob_field;
4572
unsigned char *bitmaps;
4576
if (!multi_alloc_root(session->mem_root,
4577
&table, sizeof(*table),
4578
&share, sizeof(*share),
4579
&field, (field_count + 1) * sizeof(Field*),
4580
&blob_field, (field_count+1) *sizeof(uint32_t),
4581
&bitmaps, bitmap_buffer_size(field_count)*2,
4585
memset(table, 0, sizeof(*table));
4586
memset(share, 0, sizeof(*share));
4587
table->field= field;
4589
share->blob_field= blob_field;
4590
share->fields= field_count;
4591
share->blob_ptr_size= portable_sizeof_char_ptr;
4592
table->setup_tmp_table_column_bitmaps(bitmaps);
4594
/* Create all fields and calculate the total length of record */
4595
List_iterator_fast<Create_field> it(field_list);
4596
while ((cdef= it++))
4598
*field= make_field(share, NULL, 0, cdef->length,
4599
(unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4600
f_maybe_null(cdef->pack_flag) ? 1 : 0,
4601
cdef->pack_flag, cdef->sql_type, cdef->charset,
4603
cdef->interval, cdef->field_name);
4606
(*field)->init(table);
4607
record_length+= (*field)->pack_length();
4608
if (! ((*field)->flags & NOT_NULL_FLAG))
4611
if ((*field)->flags & BLOB_FLAG)
4612
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4616
*field= NULL; /* mark the end of the list */
4617
share->blob_field[blob_count]= 0; /* mark the end of the list */
4618
share->blob_fields= blob_count;
4620
null_pack_length= (null_count + 7)/8;
4621
share->reclength= record_length + null_pack_length;
4622
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4623
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4624
if (!table->record[0])
4627
if (null_pack_length)
4629
table->null_flags= (unsigned char*) table->record[0];
4630
share->null_fields= null_count;
4631
share->null_bytes= null_pack_length;
4634
table->in_use= session; /* field->reset() may access table->in_use */
4636
/* Set up field pointers */
4637
unsigned char *null_pos= table->record[0];
4638
unsigned char *field_pos= null_pos + share->null_bytes;
4639
uint32_t null_bit= 1;
4641
for (field= table->field; *field; ++field)
4643
Field *cur_field= *field;
4644
if ((cur_field->flags & NOT_NULL_FLAG))
4645
cur_field->move_field(field_pos);
4648
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
4650
if (null_bit == (1 << 8))
4658
field_pos+= cur_field->pack_length();
4663
for (field= table->field; *field; ++field)
4664
delete *field; /* just invokes field destructor */
4669
bool Table::open_tmp_table()
4672
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4673
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4675
file->print_error(error,MYF(0)); /* purecov: inspected */
4679
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
4685
Create MyISAM temporary table
4688
create_myisam_tmp_table()
4689
keyinfo Description of the index (there is always one index)
4690
start_recinfo MyISAM's column descriptions
4691
recinfo INOUT End of MyISAM's column descriptions
4695
Create a MyISAM temporary table according to passed description. The is
4696
assumed to have one unique index or constraint.
4698
The passed array or MI_COLUMNDEF structures must have this form:
4700
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4701
when there are many nullable columns)
4703
3. One free MI_COLUMNDEF element (*recinfo points here)
4705
This function may use the free element to create hash column for unique
4713
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4714
MI_COLUMNDEF *start_recinfo,
4715
MI_COLUMNDEF **recinfo,
4720
MI_UNIQUEDEF uniquedef;
4721
TABLE_SHARE *share= s;
4724
{ // Get keys for ni_create
4725
bool using_unique_constraint=0;
4726
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4727
sizeof(*seg) * keyinfo->key_parts);
4731
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4732
if (keyinfo->key_length >= file->max_key_length() ||
4733
keyinfo->key_parts > file->max_key_parts() ||
4736
/* Can't create a key; Make a unique constraint instead of a key */
4739
using_unique_constraint=1;
4740
memset(&uniquedef, 0, sizeof(uniquedef));
4741
uniquedef.keysegs=keyinfo->key_parts;
4743
uniquedef.null_are_equal=1;
4745
/* Create extra column for hash value */
4746
memset(*recinfo, 0, sizeof(**recinfo));
4747
(*recinfo)->type= FIELD_CHECK;
4748
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4750
share->reclength+=MI_UNIQUE_HASH_LENGTH;
4754
/* Create an unique key */
4755
memset(&keydef, 0, sizeof(keydef));
4756
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4757
keydef.keysegs= keyinfo->key_parts;
4760
for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4762
Field *key_field=keyinfo->key_part[i].field;
4764
seg->language= key_field->charset()->number;
4765
seg->length= keyinfo->key_part[i].length;
4766
seg->start= keyinfo->key_part[i].offset;
4767
if (key_field->flags & BLOB_FLAG)
4770
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4771
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4772
seg->bit_start= (uint8_t)(key_field->pack_length()
4773
- share->blob_ptr_size);
4774
seg->flag= HA_BLOB_PART;
4775
seg->length=0; // Whole blob in unique constraint
4779
seg->type= keyinfo->key_part[i].type;
4781
if (!(key_field->flags & NOT_NULL_FLAG))
4783
seg->null_bit= key_field->null_bit;
4784
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4786
We are using a GROUP BY on something that contains NULL
4787
In this case we have to tell MyISAM that two NULL should
4788
on INSERT be regarded at the same value
4790
if (!using_unique_constraint)
4791
keydef.flag|= HA_NULL_ARE_EQUAL;
4795
MI_CREATE_INFO create_info;
4796
memset(&create_info, 0, sizeof(create_info));
4798
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4800
create_info.data_file_length= ~(uint64_t) 0;
4802
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4803
(uint32_t) (*recinfo-start_recinfo),
4805
share->uniques, &uniquedef,
4807
HA_CREATE_TMP_TABLE)))
4809
file->print_error(error,MYF(0)); /* purecov: inspected */
4813
status_var_increment(in_use->status_var.created_tmp_disk_tables);
4814
share->db_record_offset= 1;
4821
void Table::free_tmp_table(Session *session)
4823
MEM_ROOT own_root= mem_root;
4824
const char *save_proc_info;
4826
save_proc_info=session->get_proc_info();
4827
session->set_proc_info("removing tmp table");
4829
// Release latches since this can take a long time
4830
ha_release_temporary_latches(session);
4835
file->ha_drop_table(s->table_name.str);
4837
file->ha_delete_table(s->table_name.str);
4842
for (Field **ptr= field ; *ptr ; ptr++)
4844
free_io_cache(this);
4846
if (temp_pool_slot != MY_BIT_NONE)
4847
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4849
plugin_unlock(0, s->db_plugin);
4851
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4852
session->set_proc_info(save_proc_info);
4858
If a HEAP table gets full, create a MyISAM table and copy all rows
4862
bool create_myisam_from_heap(Session *session, Table *table,
4863
MI_COLUMNDEF *start_recinfo,
4864
MI_COLUMNDEF **recinfo,
4865
int error, bool ignore_last_dupp_key_error)
4869
const char *save_proc_info;
4872
if (table->s->db_type() != heap_hton ||
4873
error != HA_ERR_RECORD_FILE_FULL)
4875
table->file->print_error(error,MYF(0));
4879
// Release latches since this can take a long time
4880
ha_release_temporary_latches(session);
4884
new_table.s= &share;
4885
new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4886
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4887
new_table.s->db_type())))
4888
return(1); // End of memory
4890
save_proc_info=session->get_proc_info();
4891
session->set_proc_info("converting HEAP to MyISAM");
4893
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4894
recinfo, session->lex->select_lex.options |
4897
if (new_table.open_tmp_table())
4899
if (table->file->indexes_are_disabled())
4900
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4901
table->file->ha_index_or_rnd_end();
4902
table->file->ha_rnd_init(1);
4905
new_table.file->extra(HA_EXTRA_NO_ROWS);
4906
new_table.no_rows=1;
4909
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4910
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4913
copy all old rows from heap table to MyISAM table
4914
This is the only code that uses record[1] to read/write but this
4915
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4917
while (!table->file->rnd_next(new_table.record[1]))
4919
write_err= new_table.file->ha_write_row(new_table.record[1]);
4923
/* copy row that filled HEAP table */
4924
if ((write_err=new_table.file->ha_write_row(table->record[0])))
4926
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4927
!ignore_last_dupp_key_error)
4931
/* remove heap table and change to use myisam table */
4932
(void) table->file->ha_rnd_end();
4933
(void) table->file->close(); // This deletes the table !
4936
plugin_unlock(0, table->s->db_plugin);
4937
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4938
new_table.s= table->s; // Keep old share
4942
table->file->change_table_ptr(table, table->s);
4943
table->use_all_columns();
4946
const char *new_proc_info=
4947
(!strcmp(save_proc_info,"Copying to tmp table") ?
4948
"Copying to tmp table on disk" : save_proc_info);
4949
session->set_proc_info(new_proc_info);
4954
table->file->print_error(write_err, MYF(0));
4955
(void) table->file->ha_rnd_end();
4956
(void) new_table.file->close();
4958
new_table.file->ha_delete_table(new_table.s->table_name.str);
4960
delete new_table.file;
4961
session->set_proc_info(save_proc_info);
4962
table->mem_root= new_table.mem_root;
4966
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4968
my_bitmap_map *old= bitmap->bitmap;
4969
bitmap->bitmap= s->all_set.bitmap;
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4973
void Table::restore_column_map(my_bitmap_map *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
4975
read_set->bitmap= old;
1436
4978
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1438
4980
uint32_t min_length= UINT32_MAX;
1439
4981
uint32_t best= MAX_KEY;
1440
if (usable_keys->any())
4982
if (!usable_keys->is_clear_all())
1442
for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
4984
for (uint32_t nr=0; nr < s->keys ; nr++)
1444
if (usable_keys->test(nr))
4986
if (usable_keys->is_set(nr))
1446
4988
if (key_info[nr].key_length < min_length)