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, ".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 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, const string *default_value,
342
const 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(),
365
default_value->length());
367
case DRIZZLE_TYPE_NULL:
369
case DRIZZLE_TYPE_TIMESTAMP:
370
case DRIZZLE_TYPE_DATETIME:
371
case DRIZZLE_TYPE_DATE:
372
if(default_value->compare("NOW()")==0)
374
case DRIZZLE_TYPE_ENUM:
375
default_item= new Item_string(default_value->c_str(),
376
default_value->length(),
377
system_charset_info);
379
case DRIZZLE_TYPE_VARCHAR:
380
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
381
if(charset==&my_charset_bin)
383
default_item= new Item_string(default_bin_value->c_str(),
384
default_bin_value->length(),
389
default_item= new Item_string(default_value->c_str(),
390
default_value->length(),
391
system_charset_info);
394
case DRIZZLE_TYPE_VIRTUAL:
396
case DRIZZLE_TYPE_NEWDECIMAL:
397
default_item= new Item_decimal(default_value->c_str(),
398
default_value->length(),
399
system_charset_info);
406
int parse_table_proto(Session *session, drizzle::Table &table, TABLE_SHARE *share)
409
handler *handler_file= NULL;
412
LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
413
strlen(table.engine().name().c_str()) };
414
share->db_plugin= ha_resolve_by_name(session, &engine_name);
417
share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
419
drizzle::Table::TableOptions table_options;
421
if(table.has_options())
422
table_options= table.options();
424
uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
426
if(table_options.has_pack_keys())
428
if(table_options.pack_keys())
429
db_create_options|= HA_OPTION_PACK_KEYS;
431
db_create_options|= HA_OPTION_NO_PACK_KEYS;
434
if(table_options.pack_record())
435
db_create_options|= HA_OPTION_PACK_RECORD;
437
if(table_options.has_checksum())
439
if(table_options.checksum())
440
db_create_options|= HA_OPTION_CHECKSUM;
442
db_create_options|= HA_OPTION_NO_CHECKSUM;
445
if(table_options.has_delay_key_write())
447
if(table_options.delay_key_write())
448
db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
450
db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
453
/* db_create_options was stored as 2 bytes in FRM
454
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
456
share->db_create_options= (db_create_options & 0x0000FFFF);
457
share->db_options_in_use= share->db_create_options;
460
share->avg_row_length= table_options.has_avg_row_length() ?
461
table_options.avg_row_length() : 0;
463
share->page_checksum= table_options.has_page_checksum() ?
464
(table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
467
share->row_type= table_options.has_row_type() ?
468
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
470
share->block_size= table_options.has_block_size() ?
471
table_options.block_size() : 0;
473
share->table_charset= get_charset(table_options.has_collation_id()?
474
table_options.collation_id() : 0);
476
if (!share->table_charset)
478
/* unknown charset in head[38] or pre-3.23 frm */
479
if (use_mb(default_charset_info))
481
/* Warn that we may be changing the size of character columns */
482
errmsg_printf(ERRMSG_LVL_WARN,
483
_("'%s' had no or invalid character set, "
484
"and default character set is multi-byte, "
485
"so character column sizes may have changed"),
488
share->table_charset= default_charset_info;
491
share->db_record_offset= 1;
493
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
495
share->db_low_byte_first= true;
497
share->max_rows= table_options.has_max_rows() ?
498
table_options.max_rows() : 0;
500
share->min_rows= table_options.has_min_rows() ?
501
table_options.min_rows() : 0;
503
share->keys= table.indexes_size();
506
for(int indx= 0; indx < table.indexes_size(); indx++)
507
share->key_parts+= table.indexes(indx).index_part_size();
509
share->key_info= (KEY*) alloc_root(&share->mem_root,
510
table.indexes_size() * sizeof(KEY)
511
+share->key_parts*sizeof(KEY_PART_INFO));
513
KEY_PART_INFO *key_part;
515
key_part= reinterpret_cast<KEY_PART_INFO*>
516
(share->key_info+table.indexes_size());
519
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
520
sizeof(ulong*)*share->key_parts);
522
share->keynames.count= table.indexes_size();
523
share->keynames.name= NULL;
524
share->keynames.type_names= (const char**)
525
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
527
share->keynames.type_lengths= (unsigned int*)
528
alloc_root(&share->mem_root,
529
sizeof(unsigned int) * (table.indexes_size()+1));
531
share->keynames.type_names[share->keynames.count]= NULL;
532
share->keynames.type_lengths[share->keynames.count]= 0;
534
KEY* keyinfo= share->key_info;
535
for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
537
drizzle::Table::Index indx= table.indexes(keynr);
543
keyinfo->flags|= HA_NOSAME;
545
if(indx.has_options())
547
drizzle::Table::Index::IndexOptions indx_options= indx.options();
548
if(indx_options.pack_key())
549
keyinfo->flags|= HA_PACK_KEY;
551
if(indx_options.var_length_key())
552
keyinfo->flags|= HA_VAR_LENGTH_PART;
554
if(indx_options.null_part_key())
555
keyinfo->flags|= HA_NULL_PART_KEY;
557
if(indx_options.binary_pack_key())
558
keyinfo->flags|= HA_BINARY_PACK_KEY;
560
if(indx_options.has_partial_segments())
561
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
563
if(indx_options.auto_generated_key())
564
keyinfo->flags|= HA_GENERATED_KEY;
566
if(indx_options.has_key_block_size())
568
keyinfo->flags|= HA_USES_BLOCK_SIZE;
569
keyinfo->block_size= indx_options.key_block_size();
573
keyinfo->block_size= 0;
580
case drizzle::Table::Index::UNKNOWN_INDEX:
581
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
583
case drizzle::Table::Index::BTREE:
584
keyinfo->algorithm= HA_KEY_ALG_BTREE;
586
case drizzle::Table::Index::RTREE:
587
keyinfo->algorithm= HA_KEY_ALG_RTREE;
589
case drizzle::Table::Index::HASH:
590
keyinfo->algorithm= HA_KEY_ALG_HASH;
592
case drizzle::Table::Index::FULLTEXT:
593
keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
596
/* TODO: suitable warning ? */
597
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
601
keyinfo->key_length= indx.key_length();
603
keyinfo->key_parts= indx.index_part_size();
605
keyinfo->key_part= key_part;
606
keyinfo->rec_per_key= rec_per_key;
608
for(unsigned int partnr= 0;
609
partnr < keyinfo->key_parts;
610
partnr++, key_part++)
612
drizzle::Table::Index::IndexPart part;
613
part= indx.index_part(partnr);
617
key_part->field= NULL;
618
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
619
key_part->null_bit= 0;
620
/* key_part->null_offset is only set if null_bit (see later) */
621
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
622
/* key_part->type ???? */
623
key_part->key_part_flag= 0;
624
if(part.has_in_reverse_order())
625
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
627
key_part->length= part.compare_length();
629
key_part->store_length= key_part->length;
631
/* key_part->offset is set later */
632
key_part->key_type= part.key_type();
636
if(!indx.has_comment())
638
keyinfo->comment.length= 0;
639
keyinfo->comment.str= NULL;
643
keyinfo->flags|= HA_USES_COMMENT;
644
keyinfo->comment.length= indx.comment().length();
645
keyinfo->comment.str= strmake_root(&share->mem_root,
646
indx.comment().c_str(),
647
keyinfo->comment.length);
650
keyinfo->name= strmake_root(&share->mem_root,
652
indx.name().length());
654
share->keynames.type_names[keynr]= keyinfo->name;
655
share->keynames.type_lengths[keynr]= indx.name().length();
658
share->keys_for_keyread.init(0);
659
share->keys_in_use.init(share->keys);
661
if(table_options.has_connect_string())
663
size_t len= table_options.connect_string().length();
664
const char* str= table_options.connect_string().c_str();
666
share->connect_string.length= len;
667
share->connect_string.str= strmake_root(&share->mem_root, str, len);
670
if(table_options.has_comment())
672
size_t len= table_options.comment().length();
673
const char* str= table_options.comment().c_str();
675
share->comment.length= len;
676
share->comment.str= strmake_root(&share->mem_root, str, len);
679
share->key_block_size= table_options.has_key_block_size() ?
680
table_options.key_block_size() : 0;
682
share->fields= table.field_size();
684
share->stored_fields= share->fields;
686
share->field= (Field**) alloc_root(&share->mem_root,
687
((share->fields+1) * sizeof(Field*)));
688
share->field[share->fields]= NULL;
690
uint32_t null_fields= 0;
693
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
694
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
696
assert(field_offsets && field_pack_length); // TODO: fixme
698
uint32_t interval_count= 0;
699
uint32_t interval_parts= 0;
701
uint32_t stored_columns_reclength= 0;
703
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
705
drizzle::Table::Field pfield= table.field(fieldnr);
706
if(pfield.has_constraints() && pfield.constraints().is_nullable())
709
bool field_is_stored= true;
711
enum_field_types drizzle_field_type=
712
proto_field_type_to_drizzle_type(pfield.type());
714
if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
716
drizzle::Table::Field::VirtualFieldOptions field_options=
717
pfield.virtual_options();
719
drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
721
field_is_stored= field_options.physically_stored();
724
field_offsets[fieldnr]= stored_columns_reclength;
726
/* the below switch is very similar to
727
Create_field::create_length_to_internal_length in field.cc
728
(which should one day be replace by just this code)
730
switch(drizzle_field_type)
732
case DRIZZLE_TYPE_BLOB:
733
case DRIZZLE_TYPE_VARCHAR:
735
drizzle::Table::Field::StringFieldOptions field_options=
736
pfield.string_options();
738
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
739
field_options.collation_id() : 0);
742
cs= default_charset_info;
744
field_pack_length[fieldnr]=
745
calc_pack_length(drizzle_field_type,
746
field_options.length() * cs->mbmaxlen);
750
case DRIZZLE_TYPE_ENUM:
752
drizzle::Table::Field::SetFieldOptions field_options=
753
pfield.set_options();
755
field_pack_length[fieldnr]=
756
get_enum_pack_length(field_options.field_value_size());
759
interval_parts+= field_options.field_value_size();
762
case DRIZZLE_TYPE_NEWDECIMAL:
764
drizzle::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
766
field_pack_length[fieldnr]=
767
my_decimal_get_binary_size(fo.precision(), fo.scale());
771
/* Zero is okay here as length is fixed for other types. */
772
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
775
share->reclength+= field_pack_length[fieldnr];
778
stored_columns_reclength+= field_pack_length[fieldnr];
781
/* data_offset added to stored_rec_length later */
782
share->stored_rec_length= stored_columns_reclength;
784
/* fix up offsets for non-stored fields (at end of record) */
785
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
787
drizzle::Table::Field pfield= table.field(fieldnr);
789
bool field_is_stored= true;
791
enum_field_types drizzle_field_type=
792
proto_field_type_to_drizzle_type(pfield.type());
794
if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
796
drizzle::Table::Field::VirtualFieldOptions field_options=
797
pfield.virtual_options();
799
field_is_stored= field_options.physically_stored();
804
field_offsets[fieldnr]= stored_columns_reclength;
805
stored_columns_reclength+= field_pack_length[fieldnr];
808
share->null_fields= null_fields;
810
ulong null_bits= null_fields;
811
if(!table_options.pack_record())
813
ulong data_offset= (null_bits + 7)/8;
816
share->reclength+= data_offset;
817
share->stored_rec_length+= data_offset;
819
ulong rec_buff_length;
821
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
822
share->rec_buff_length= rec_buff_length;
824
unsigned char* record= NULL;
826
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
830
memset(record, 0, rec_buff_length);
834
if(!table_options.pack_record())
836
null_count++; // one bit for delete mark.
840
share->default_values= record;
844
share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
845
interval_count*sizeof(TYPELIB));
848
share->intervals= NULL;
850
share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
851
(share->fields+1)*sizeof(char*));
853
share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
854
(share->fields+1)*sizeof(unsigned int));
856
share->fieldnames.type_names[share->fields]= NULL;
857
share->fieldnames.type_lengths[share->fields]= 0;
858
share->fieldnames.count= share->fields;
861
/* Now fix the TYPELIBs for the intervals (enum values)
865
uint32_t interval_nr= 0;
867
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
869
drizzle::Table::Field pfield= table.field(fieldnr);
872
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
873
pfield.name().c_str(),
874
pfield.name().length());
876
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
879
if(pfield.type() != drizzle::Table::Field::ENUM)
882
drizzle::Table::Field::SetFieldOptions field_options=
883
pfield.set_options();
885
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
886
field_options.collation_id() : 0);
889
charset= default_charset_info;
891
TYPELIB *t= &(share->intervals[interval_nr]);
893
t->type_names= (const char**)alloc_root(&share->mem_root,
894
(field_options.field_value_size()+1)*sizeof(char*));
896
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
897
(field_options.field_value_size()+1)*sizeof(unsigned int));
899
t->type_names[field_options.field_value_size()]= NULL;
900
t->type_lengths[field_options.field_value_size()]= 0;
902
t->count= field_options.field_value_size();
905
for(int n=0; n < field_options.field_value_size(); n++)
907
t->type_names[n]= strmake_root(&share->mem_root,
908
field_options.field_value(n).c_str(),
909
field_options.field_value(n).length());
911
/* Go ask the charset what the length is as for "" length=1
912
and there's stripping spaces or some other crack going on.
915
lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
916
field_options.field_value(n).length());
917
t->type_lengths[n]= lengthsp;
923
/* and read the fields */
926
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
929
use_hash= !hash_init(&share->name_hash,
932
(hash_get_key) get_field_name, 0, 0);
934
unsigned char* null_pos= record;;
935
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
937
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
939
drizzle::Table::Field pfield= table.field(fieldnr);
941
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
943
switch(pfield.format())
945
case drizzle::Table::Field::DefaultFormat:
946
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
948
case drizzle::Table::Field::FixedFormat:
949
column_format= COLUMN_FORMAT_TYPE_FIXED;
951
case drizzle::Table::Field::DynamicFormat:
952
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
958
Field::utype unireg_type= Field::NONE;
960
if(pfield.has_numeric_options()
961
&& pfield.numeric_options().is_autoincrement())
963
unireg_type= Field::NEXT_NUMBER;
966
if(pfield.has_options()
967
&& pfield.options().has_default_value()
968
&& pfield.options().default_value().compare("NOW()")==0)
970
if(pfield.options().has_update_value()
971
&& pfield.options().update_value().compare("NOW()")==0)
973
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
975
else if (!pfield.options().has_update_value())
977
unireg_type= Field::TIMESTAMP_DN_FIELD;
980
assert(1); // Invalid update value.
982
else if (pfield.has_options()
983
&& pfield.options().has_update_value()
984
&& pfield.options().update_value().compare("NOW()")==0)
986
unireg_type= Field::TIMESTAMP_UN_FIELD;
990
if(!pfield.has_comment())
992
comment.str= (char*)"";
997
size_t len= pfield.comment().length();
998
const char* str= pfield.comment().c_str();
1000
comment.str= strmake_root(&share->mem_root, str, len);
1001
comment.length= len;
1004
enum_field_types field_type;
1005
virtual_column_info *vcol_info= NULL;
1006
bool field_is_stored= true;
1009
field_type= proto_field_type_to_drizzle_type(pfield.type());
1011
if(field_type==DRIZZLE_TYPE_VIRTUAL)
1013
drizzle::Table::Field::VirtualFieldOptions field_options=
1014
pfield.virtual_options();
1016
vcol_info= new virtual_column_info();
1017
field_type= proto_field_type_to_drizzle_type(field_options.type());
1018
field_is_stored= field_options.physically_stored();
1020
size_t len= field_options.expression().length();
1021
const char* str= field_options.expression().c_str();
1023
vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
1024
vcol_info->expr_str.length= len;
1029
const CHARSET_INFO *charset= &my_charset_bin;
1031
if(field_type==DRIZZLE_TYPE_BLOB
1032
|| field_type==DRIZZLE_TYPE_VARCHAR)
1034
drizzle::Table::Field::StringFieldOptions field_options=
1035
pfield.string_options();
1037
charset= get_charset(field_options.has_collation_id()?
1038
field_options.collation_id() : 0);
1041
charset= default_charset_info;
1045
if(field_type==DRIZZLE_TYPE_ENUM)
1047
drizzle::Table::Field::SetFieldOptions field_options=
1048
pfield.set_options();
1050
charset= get_charset(field_options.has_collation_id()?
1051
field_options.collation_id() : 0);
1054
charset= default_charset_info;
1058
Item *default_value= NULL;
1060
if(pfield.options().has_default_value()
1061
|| pfield.options().has_default_null()
1062
|| pfield.options().has_default_bin_value())
1064
default_value= default_value_item(field_type,
1066
pfield.options().default_null(),
1067
&pfield.options().default_value(),
1068
&pfield.options().default_bin_value());
1071
uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
1073
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
1074
memset(&temp_table, 0, sizeof(temp_table));
1075
temp_table.s= share;
1076
temp_table.in_use= session;
1077
temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
1078
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
1080
Field* f= make_field(share, &share->mem_root,
1081
record+field_offsets[fieldnr]+data_offset,
1082
pfield.options().length(),
1088
(Field::utype) MTYP_TYPENR(unireg_type),
1089
((field_type==DRIZZLE_TYPE_ENUM)?
1090
share->intervals+(interval_nr++)
1092
share->fieldnames.type_names[fieldnr]);
1094
share->field[fieldnr]= f;
1096
f->init(&temp_table); /* blob default values need table obj */
1098
if(!(f->flags & NOT_NULL_FLAG))
1100
*f->null_ptr|= f->null_bit;
1101
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
1108
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1109
session->count_cuted_fields= CHECK_FIELD_WARN;
1110
int res= default_value->save_in_field(f, 1);
1111
session->count_cuted_fields= old_count_cuted_fields;
1112
if (res != 0 && res != 3)
1114
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
1119
else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
1120
(f->flags & NOT_NULL_FLAG))
1123
f->store((int64_t) 1, true);
1128
/* hack to undo f->init() */
1130
f->orig_table= NULL;
1132
f->field_index= fieldnr;
1133
f->comment= comment;
1134
f->vcol_info= vcol_info;
1135
f->is_stored= field_is_stored;
1137
&& !(f->unireg_check==Field::NEXT_NUMBER)
1138
&& (f->flags & NOT_NULL_FLAG)
1139
&& (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
1140
f->flags|= NO_DEFAULT_VALUE_FLAG;
1142
if(f->unireg_check == Field::NEXT_NUMBER)
1143
share->found_next_number_field= &(share->field[fieldnr]);
1145
if(share->timestamp_field == f)
1146
share->timestamp_field_offset= fieldnr;
1148
if (use_hash) /* supposedly this never fails... but comments lie */
1149
(void) my_hash_insert(&share->name_hash,
1150
(unsigned char*)&(share->field[fieldnr]));
1154
share->stored_fields--;
1158
keyinfo= share->key_info;
1159
for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
1161
key_part= keyinfo->key_part;
1163
for(unsigned int partnr= 0;
1164
partnr < keyinfo->key_parts;
1165
partnr++, key_part++)
1167
/* Fix up key_part->offset by adding data_offset.
1168
We really should compute offset as well.
1169
But at least this way we are a little better. */
1170
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1175
We need to set the unused bits to 1. If the number of bits is a multiple
1176
of 8 there are no unused bits.
1180
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1182
share->null_bytes= (null_pos - (unsigned char*) record +
1183
(null_bit_pos + 7) / 8);
1185
share->last_null_bit_pos= null_bit_pos;
1187
free(field_offsets);
1188
free(field_pack_length);
1190
if(!(handler_file= get_new_handler(share, session->mem_root,
1195
if (share->key_parts)
1197
uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
1198
&share->keynames, 3) - 1);
1200
int64_t ha_option= handler_file->ha_table_flags();
1202
keyinfo= share->key_info;
1203
key_part= keyinfo->key_part;
1205
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1207
uint32_t usable_parts= 0;
1209
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1212
If the UNIQUE key doesn't have NULL columns and is not a part key
1213
declare this as a primary key.
1216
for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
1218
uint32_t fieldnr= key_part[i].fieldnr;
1220
share->field[fieldnr-1]->null_ptr ||
1221
share->field[fieldnr-1]->key_length() !=
1224
primary_key=MAX_KEY; // Can't be used
1230
for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1233
if (!key_part->fieldnr)
1235
// error= 4; // Wrong file
1236
abort(); // goto err;
1238
field= key_part->field= share->field[key_part->fieldnr-1];
1239
key_part->type= field->key_type();
1240
if (field->null_ptr)
1242
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1243
share->default_values);
1244
key_part->null_bit= field->null_bit;
1245
key_part->store_length+=HA_KEY_NULL_LENGTH;
1246
keyinfo->flags|=HA_NULL_PART_KEY;
1247
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1248
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1250
if (field->type() == DRIZZLE_TYPE_BLOB ||
1251
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1253
if (field->type() == DRIZZLE_TYPE_BLOB)
1254
key_part->key_part_flag|= HA_BLOB_PART;
1256
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1257
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1258
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1259
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1261
if (i == 0 && key != primary_key)
1262
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1263
(keyinfo->key_parts == 1)) ?
1264
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1266
field->key_start.set_bit(key);
1267
if (field->key_length() == key_part->length &&
1268
!(field->flags & BLOB_FLAG))
1270
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1272
share->keys_for_keyread.set_bit(key);
1273
field->part_of_key.set_bit(key);
1274
field->part_of_key_not_clustered.set_bit(key);
1276
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1277
field->part_of_sortkey.set_bit(key);
1279
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1281
usable_parts++; // For FILESORT
1282
field->flags|= PART_KEY_FLAG;
1283
if (key == primary_key)
1285
field->flags|= PRI_KEY_FLAG;
1287
If this field is part of the primary key and all keys contains
1288
the primary key, then we can use any key to find this column
1290
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1292
field->part_of_key= share->keys_in_use;
1293
if (field->part_of_sortkey.is_set(key))
1294
field->part_of_sortkey= share->keys_in_use;
1297
if (field->key_length() != key_part->length)
1299
key_part->key_part_flag|= HA_PART_KEY_SEG;
1302
keyinfo->usable_key_parts= usable_parts; // Filesort
1304
set_if_bigger(share->max_key_length,keyinfo->key_length+
1305
keyinfo->key_parts);
1306
share->total_key_length+= keyinfo->key_length;
1308
MERGE tables do not have unique indexes. But every key could be
1309
an unique index on the underlying MyISAM table. (Bug #10400)
1311
if ((keyinfo->flags & HA_NOSAME) ||
1312
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1313
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1315
if (primary_key < MAX_KEY &&
1316
(share->keys_in_use.is_set(primary_key)))
1318
share->primary_key= primary_key;
1320
If we are using an integer as the primary key then allow the user to
1321
refer to it as '_rowid'
1323
if (share->key_info[primary_key].key_parts == 1)
1325
Field *field= share->key_info[primary_key].key_part[0].field;
1326
if (field && field->result_type() == INT_RESULT)
1328
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1329
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1336
share->primary_key = MAX_KEY; // we do not have a primary key
1339
share->primary_key= MAX_KEY;
1341
if (share->found_next_number_field)
1343
Field *reg_field= *share->found_next_number_field;
1344
if ((int) (share->next_number_index= (uint32_t)
1345
find_ref_key(share->key_info, share->keys,
1346
share->default_values, reg_field,
1347
&share->next_number_key_offset,
1348
&share->next_number_keypart)) < 0)
1350
/* Wrong field definition */
1355
reg_field->flags |= AUTO_INCREMENT_FLAG;
1358
if (share->blob_fields)
1363
/* Store offsets to blob fields to find them fast */
1364
if (!(share->blob_field= save=
1365
(uint*) alloc_root(&share->mem_root,
1366
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1368
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1370
if ((*ptr)->flags & BLOB_FLAG)
1375
share->db_low_byte_first= handler_file->low_byte_first();
1376
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1378
my_bitmap_map *bitmaps;
1380
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1381
share->column_bitmap_size)))
1383
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1384
bitmap_set_all(&share->all_set);
1387
delete handler_file;
1391
share->error= error;
1392
share->open_errno= my_errno;
1394
hash_free(&share->name_hash);
1396
delete handler_file;
1397
open_table_error(share, error, share->open_errno, 0);
1402
Read table definition from a binary / text based .frm file
1406
session Thread handler
1407
share Fill this with table definition
1408
db_flags Bit mask of the following flags: OPEN_VIEW
1411
This function is called when the table definition is not cached in
1413
The data is returned in 'share', which is alloced by
1414
alloc_table_share().. The code assumes that share is initialized.
1418
1 Error (see open_table_error)
1419
2 Error (see open_table_error)
1420
3 Wrong data in .frm file
1421
4 Error (see open_table_error)
1422
5 Error (see open_table_error: charset unavailable)
1423
6 Unknown .frm version
1426
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
1430
string proto_path("");
1435
proto_path.reserve(FN_REFLEN);
1436
proto_path.append(share->normalized_path.str);
1438
proto_path.append(".dfe");
1440
drizzle::Table table;
1442
if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
1451
if(!table.IsInitialized())
1459
error= parse_table_proto(session, table, share);
1461
share->table_category= get_table_category(& share->db, & share->table_name);
1464
session->status_var.opened_shares++;
1467
if (error && !error_given)
1469
share->error= error;
1470
open_table_error(share, error, (share->open_errno= my_errno), 0);
1477
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1478
This routine is used for error handling purposes.
1482
table Table object for which virtual columns are set-up
1487
static void clear_field_flag(Table *table)
1491
for (ptr= table->field; *ptr; ptr++)
1492
(*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1496
The function uses the feature in fix_fields where the flag
1497
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1498
This field must always be reset before returning from the function
1499
since it is used for other purposes as well.
1502
fix_fields_vcol_func()
1503
session The thread object
1504
func_item The item tree reference of the virtual columnfunction
1505
table The table object
1506
field_name The name of the processed field
1509
true An error occurred, something was wrong with the
1511
false Ok, a partition field array was created
1514
bool fix_fields_vcol_func(Session *session,
1517
const char *field_name)
1519
uint32_t dir_length, home_dir_length;
1522
TableList *save_table_list, *save_first_table, *save_last_table;
1524
Name_resolution_context *context;
1525
const char *save_where;
1527
char db_name_string[FN_REFLEN];
1528
bool save_use_only_table_context;
1529
Field **ptr, *field;
1530
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1534
Set-up the TABLE_LIST object to be a list with a single table
1535
Set the object to zero to create NULL pointers and set alias
1536
and real name to table name and get database name from file name.
1539
bzero((void*)&tables, sizeof(TableList));
1540
tables.alias= tables.table_name= (char*) table->s->table_name.str;
1541
tables.table= table;
1542
tables.next_local= NULL;
1543
tables.next_name_resolution_table= NULL;
1544
memcpy(db_name_string,
1545
table->s->normalized_path.str,
1546
table->s->normalized_path.length);
1547
db_name_string[table->s->normalized_path.length]= '\0';
1548
dir_length= dirname_length(db_name_string);
1549
db_name_string[dir_length - 1]= 0;
1550
home_dir_length= dirname_length(db_name_string);
1551
db_name= &db_name_string[home_dir_length];
1554
session->mark_used_columns= MARK_COLUMNS_NONE;
1556
context= session->lex->current_context();
1557
table->map= 1; //To ensure correct calculation of const item
1558
table->get_fields_in_item_tree= true;
1559
save_table_list= context->table_list;
1560
save_first_table= context->first_name_resolution_table;
1561
save_last_table= context->last_name_resolution_table;
1562
context->table_list= &tables;
1563
context->first_name_resolution_table= &tables;
1564
context->last_name_resolution_table= NULL;
1565
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1566
save_where= session->where;
1567
session->where= "virtual column function";
1569
/* Save the context before fixing the fields*/
1570
save_use_only_table_context= session->lex->use_only_table_context;
1571
session->lex->use_only_table_context= true;
1572
/* Fix fields referenced to by the virtual column function */
1573
error= func_expr->fix_fields(session, (Item**)0);
1574
/* Restore the original context*/
1575
session->lex->use_only_table_context= save_use_only_table_context;
1576
context->table_list= save_table_list;
1577
context->first_name_resolution_table= save_first_table;
1578
context->last_name_resolution_table= save_last_table;
1580
if (unlikely(error))
1582
clear_field_flag(table);
1585
session->where= save_where;
1587
Walk through the Item tree checking if all items are valid
1588
to be part of the virtual column
1590
error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1593
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1594
clear_field_flag(table);
1597
if (unlikely(func_expr->const_item()))
1599
my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1600
clear_field_flag(table);
1603
/* Ensure that this virtual column is not based on another virtual field. */
1605
while ((field= *(ptr++)))
1607
if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1610
my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1611
clear_field_flag(table);
1616
Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1617
when calling fix_fields.
1619
clear_field_flag(table);
1623
table->get_fields_in_item_tree= false;
1624
session->mark_used_columns= save_mark_used_columns;
1625
table->map= 0; //Restore old value
1630
Unpack the definition of a virtual column
1633
unpack_vcol_info_from_frm()
1634
session Thread handler
1635
table Table with the checked field
1636
field Pointer to Field object
1637
open_mode Open table mode needed to determine
1638
which errors need to be generated in a failure
1639
error_reported updated flag for the caller that no other error
1640
messages are to be generated.
1646
bool unpack_vcol_info_from_frm(Session *session,
1649
LEX_STRING *vcol_expr,
1650
open_table_mode open_mode,
1651
bool *error_reported)
1656
Step 1: Construct a statement for the parser.
1657
The parsed string needs to take the following format:
1658
"PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1660
char *vcol_expr_str;
1663
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1665
parse_vcol_keyword.length + 3)))
1669
memcpy(vcol_expr_str,
1670
(char*) parse_vcol_keyword.str,
1671
parse_vcol_keyword.length);
1672
str_len= parse_vcol_keyword.length;
1673
memcpy(vcol_expr_str + str_len, "(", 1);
1675
memcpy(vcol_expr_str + str_len,
1676
(char*) vcol_expr->str,
1678
str_len+= vcol_expr->length;
1679
memcpy(vcol_expr_str + str_len, ")", 1);
1681
memcpy(vcol_expr_str + str_len, "\0", 1);
1683
Lex_input_stream lip(session, vcol_expr_str, str_len);
1686
Step 2: Setup session for parsing.
1687
1) make Item objects be created in the memory allocated for the Table
1688
object (not TABLE_SHARE)
1689
2) ensure that created Item's are not put on to session->free_list
1690
(which is associated with the parsed statement and hence cleared after
1692
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1693
to be parsed as a SQL command.
1695
MEM_ROOT **root_ptr, *old_root;
1696
Item *backup_free_list= session->free_list;
1697
root_ptr= current_mem_root_ptr();
1698
old_root= *root_ptr;
1699
*root_ptr= &table->mem_root;
1700
session->free_list= NULL;
1701
session->lex->parse_vcol_expr= true;
1704
Step 3: Use the parser to build an Item object from.
1706
if (parse_sql(session, &lip))
1710
/* From now on use vcol_info generated by the parser. */
1711
field->vcol_info= session->lex->vcol_info;
1713
/* Validate the Item tree. */
1714
if (fix_fields_vcol_func(session,
1715
field->vcol_info->expr_item,
1719
if (open_mode == OTM_CREATE)
1722
During CREATE/ALTER TABLE it is ok to receive errors here.
1723
It is not ok if it happens during the opening of an frm
1724
file as part of a normal query.
1726
*error_reported= true;
1728
field->vcol_info= NULL;
1731
field->vcol_info->item_free_list= session->free_list;
1732
session->free_list= backup_free_list;
1733
*root_ptr= old_root;
1738
session->lex->parse_vcol_expr= false;
1739
session->free_items();
1740
*root_ptr= old_root;
1741
session->free_list= backup_free_list;
1747
Open a table based on a TABLE_SHARE
1750
open_table_from_share()
1751
session Thread handler
1752
share Table definition
1753
alias Alias for table
1754
db_stat open flags (for example HA_OPEN_KEYFILE|
1755
HA_OPEN_RNDFILE..) can be 0 (example in
1757
prgflag READ_ALL etc..
1758
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1759
outparam result table
1760
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1761
if OTM_CREATE some errors are ignore
1762
if OTM_ALTER HA_OPEN is not called
1766
1 Error (see open_table_error)
1767
2 Error (see open_table_error)
1768
3 Wrong data in .frm file
1769
4 Error (see open_table_error)
1770
5 Error (see open_table_error: charset unavailable)
1771
7 Table definition has changed in engine
1774
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1775
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1776
Table *outparam, open_table_mode open_mode)
1779
uint32_t records, i, bitmap_size;
1780
bool error_reported= false;
1781
unsigned char *record, *bitmaps;
1782
Field **field_ptr, **vfield_ptr;
1784
/* Parsing of partitioning information from .frm needs session->lex set up. */
1785
assert(session->lex->is_lex_started);
1788
memset(outparam, 0, sizeof(*outparam));
1789
outparam->in_use= session;
1791
outparam->db_stat= db_stat;
1792
outparam->write_row_record= NULL;
1794
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1796
if (!(outparam->alias= strdup(alias)))
1798
outparam->quick_keys.init();
1799
outparam->covering_keys.init();
1800
outparam->keys_in_use_for_query.init();
1802
/* Allocate handler */
1804
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1806
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1816
outparam->reginfo.lock_type= TL_UNLOCK;
1817
outparam->current_lock= F_UNLCK;
1819
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1821
if (prgflag & (READ_ALL+EXTRA_RECORD))
1824
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1825
share->rec_buff_length * records)))
1826
goto err; /* purecov: inspected */
1830
/* We are probably in hard repair, and the buffers should not be used */
1831
outparam->record[0]= outparam->record[1]= share->default_values;
1835
outparam->record[0]= record;
1837
outparam->record[1]= record+ share->rec_buff_length;
1839
outparam->record[1]= outparam->record[0]; // Safety
1844
We need this because when we read var-length rows, we are not updating
1845
bytes after end of varchar
1849
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1850
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1852
memcpy(outparam->record[1], share->default_values,
1853
share->rec_buff_length);
1857
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1858
(uint32_t) ((share->fields+1)*
1860
goto err; /* purecov: inspected */
1862
outparam->field= field_ptr;
1864
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1866
outparam->null_flags= (unsigned char*) record+1;
1868
/* Setup copy of fields from share, but use the right alias and record */
1869
for (i=0 ; i < share->fields; i++, field_ptr++)
1871
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1874
(*field_ptr)= 0; // End marker
1876
if (share->found_next_number_field)
1877
outparam->found_next_number_field=
1878
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1879
if (share->timestamp_field)
1880
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1883
/* Fix key->name and key_part->field */
1884
if (share->key_parts)
1886
KEY *key_info, *key_info_end;
1887
KEY_PART_INFO *key_part;
1889
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1890
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1892
outparam->key_info= key_info;
1893
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1895
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1896
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1899
for (key_info_end= key_info + share->keys ;
1900
key_info < key_info_end ;
1903
KEY_PART_INFO *key_part_end;
1905
key_info->table= outparam;
1906
key_info->key_part= key_part;
1908
for (key_part_end= key_part+ key_info->key_parts ;
1909
key_part < key_part_end ;
1912
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1914
if (field->key_length() != key_part->length &&
1915
!(field->flags & BLOB_FLAG))
1918
We are using only a prefix of the column as a key:
1919
Create a new field for the key part that matches the index
1921
field= key_part->field=field->new_field(&outparam->mem_root,
1923
field->field_length= key_part->length;
1930
Process virtual columns, if any.
1932
if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
1933
(uint32_t) ((share->vfields+1)*
1937
outparam->vfield= vfield_ptr;
1939
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
1941
if ((*field_ptr)->vcol_info)
1943
if (unpack_vcol_info_from_frm(session,
1946
&(*field_ptr)->vcol_info->expr_str,
1950
error= 4; // in case no error is reported
1953
*(vfield_ptr++)= *field_ptr;
1956
*vfield_ptr= NULL; // End marker
1957
/* Check virtual columns against table's storage engine. */
1958
if ((share->vfields && outparam->file) &&
1959
(not outparam->file->check_if_supported_virtual_columns()))
1961
my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
1963
"Specified storage engine");
1964
error_reported= true;
1968
/* Allocate bitmaps */
1970
bitmap_size= share->column_bitmap_size;
1971
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1973
bitmap_init(&outparam->def_read_set,
1974
(my_bitmap_map*) bitmaps, share->fields, false);
1975
bitmap_init(&outparam->def_write_set,
1976
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1977
bitmap_init(&outparam->tmp_set,
1978
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1979
outparam->default_column_bitmaps();
1981
/* The table struct is now initialized; Open the table */
1983
if (db_stat && open_mode != OTM_ALTER)
1986
if ((ha_err= (outparam->file->
1987
ha_open(outparam, share->normalized_path.str,
1988
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1989
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1990
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1991
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1992
HA_OPEN_ABORT_IF_LOCKED :
1993
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1995
/* Set a flag if the table is crashed and it can be auto. repaired */
1996
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1997
outparam->file->auto_repair() &&
1998
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
2002
case HA_ERR_NO_SUCH_TABLE:
2004
The table did not exists in storage engine, use same error message
2005
as if the .frm file didn't exist
2012
Too many files opened, use same error message as if the .frm
2019
outparam->file->print_error(ha_err, MYF(0));
2020
error_reported= true;
2021
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
2025
goto err; /* purecov: inspected */
2029
#if defined(HAVE_purify)
2030
memset(bitmaps, 0, bitmap_size*3);
2033
outparam->no_replicate= outparam->file;
2034
session->status_var.opened_tables++;
2039
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
2040
open_table_error(share, error, my_errno, 0);
2041
delete outparam->file;
2042
outparam->file= 0; // For easier error checking
2043
outparam->db_stat=0;
2044
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
2045
free((char*) outparam->alias);
2049
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
2050
uint32_t Table::tmpkeyval()
2052
return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
2056
Free information allocated by openfrm
2060
table Table object to free
2061
free_share Is 1 if we also want to free table_share
2064
int Table::closefrm(bool free_share)
83
error= cursor->close();
2069
error= file->close();
2070
free((char*) alias);
87
2074
for (Field **ptr=field ; *ptr ; ptr++)
94
cursor= 0; /* For easier errorchecking */
2079
file= 0; /* For easier errorchecking */
2082
if (s->tmp_table == NO_TMP_TABLE)
2083
release_table_share(s, RELEASE_NORMAL);
2085
free_table_share(s);
2087
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
2093
/* Deallocate temporary blob storage */
1398
4425
session->mem_root= mem_root_save;
4426
table->free_tmp_table(session); /* purecov: inspected */
4427
if (temp_pool_slot != MY_BIT_NONE)
4428
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4429
return(NULL); /* purecov: inspected */
1404
4432
/****************************************************************************/
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;
4435
Create a reduced Table object with properly set up Field list from a
4436
list of field definitions.
4438
The created table doesn't have a table handler associated with
4439
it, has no keys, no group/distinct, no copy_funcs array.
4440
The sole purpose of this Table object is to use the power of Field
4441
class to read/write data to/from table->record[0]. Then one can store
4442
the record in any container (RB tree, hash, etc).
4443
The table is created in Session mem_root, so are the table's fields.
4444
Consequently, if you don't BLOB fields, you don't need to free it.
4446
@param session connection handle
4447
@param field_list list of column definitions
4450
0 if out of memory, Table object in case of success
4453
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4455
uint32_t field_count= field_list.elements;
4456
uint32_t blob_count= 0;
4458
Create_field *cdef; /* column definition */
4459
uint32_t record_length= 0;
4460
uint32_t null_count= 0; /* number of columns which may be null */
4461
uint32_t null_pack_length; /* NULL representation array length */
4462
uint32_t *blob_field;
4463
unsigned char *bitmaps;
4467
if (!multi_alloc_root(session->mem_root,
4468
&table, sizeof(*table),
4469
&share, sizeof(*share),
4470
&field, (field_count + 1) * sizeof(Field*),
4471
&blob_field, (field_count+1) *sizeof(uint32_t),
4472
&bitmaps, bitmap_buffer_size(field_count)*2,
4476
memset(table, 0, sizeof(*table));
4477
memset(share, 0, sizeof(*share));
4478
table->field= field;
4480
share->blob_field= blob_field;
4481
share->fields= field_count;
4482
share->blob_ptr_size= portable_sizeof_char_ptr;
4483
table->setup_tmp_table_column_bitmaps(bitmaps);
4485
/* Create all fields and calculate the total length of record */
4486
List_iterator_fast<Create_field> it(field_list);
4487
while ((cdef= it++))
4489
*field= make_field(share, NULL, 0, cdef->length,
4490
(unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4491
f_maybe_null(cdef->pack_flag) ? 1 : 0,
4492
cdef->pack_flag, cdef->sql_type, cdef->charset,
4494
cdef->interval, cdef->field_name);
4497
(*field)->init(table);
4498
record_length+= (*field)->pack_length();
4499
if (! ((*field)->flags & NOT_NULL_FLAG))
4502
if ((*field)->flags & BLOB_FLAG)
4503
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4507
*field= NULL; /* mark the end of the list */
4508
share->blob_field[blob_count]= 0; /* mark the end of the list */
4509
share->blob_fields= blob_count;
4511
null_pack_length= (null_count + 7)/8;
4512
share->reclength= record_length + null_pack_length;
4513
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4514
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4515
if (!table->record[0])
4518
if (null_pack_length)
4520
table->null_flags= (unsigned char*) table->record[0];
4521
share->null_fields= null_count;
4522
share->null_bytes= null_pack_length;
4525
table->in_use= session; /* field->reset() may access table->in_use */
4527
/* Set up field pointers */
4528
unsigned char *null_pos= table->record[0];
4529
unsigned char *field_pos= null_pos + share->null_bytes;
4530
uint32_t null_bit= 1;
4532
for (field= table->field; *field; ++field)
4534
Field *cur_field= *field;
4535
if ((cur_field->flags & NOT_NULL_FLAG))
4536
cur_field->move_field(field_pos);
4539
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
4541
if (null_bit == (1 << 8))
4549
field_pos+= cur_field->pack_length();
4554
for (field= table->field; *field; ++field)
4555
delete *field; /* just invokes field destructor */
4560
bool Table::open_tmp_table()
4563
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4564
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4566
file->print_error(error,MYF(0)); /* purecov: inspected */
4570
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
4576
Create MyISAM temporary table
4579
create_myisam_tmp_table()
4580
keyinfo Description of the index (there is always one index)
4581
start_recinfo MyISAM's column descriptions
4582
recinfo INOUT End of MyISAM's column descriptions
4586
Create a MyISAM temporary table according to passed description. The is
4587
assumed to have one unique index or constraint.
4589
The passed array or MI_COLUMNDEF structures must have this form:
4591
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4592
when there are many nullable columns)
4594
3. One free MI_COLUMNDEF element (*recinfo points here)
4596
This function may use the free element to create hash column for unique
4604
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4605
MI_COLUMNDEF *start_recinfo,
4606
MI_COLUMNDEF **recinfo,
4611
MI_UNIQUEDEF uniquedef;
4612
TABLE_SHARE *share= s;
4615
{ // Get keys for ni_create
4616
bool using_unique_constraint=0;
4617
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4618
sizeof(*seg) * keyinfo->key_parts);
4622
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4623
if (keyinfo->key_length >= file->max_key_length() ||
4624
keyinfo->key_parts > file->max_key_parts() ||
4627
/* Can't create a key; Make a unique constraint instead of a key */
4630
using_unique_constraint=1;
4631
memset(&uniquedef, 0, sizeof(uniquedef));
4632
uniquedef.keysegs=keyinfo->key_parts;
4634
uniquedef.null_are_equal=1;
4636
/* Create extra column for hash value */
4637
memset(*recinfo, 0, sizeof(**recinfo));
4638
(*recinfo)->type= FIELD_CHECK;
4639
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4641
share->reclength+=MI_UNIQUE_HASH_LENGTH;
4645
/* Create an unique key */
4646
memset(&keydef, 0, sizeof(keydef));
4647
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4648
keydef.keysegs= keyinfo->key_parts;
4651
for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4653
Field *key_field=keyinfo->key_part[i].field;
4655
seg->language= key_field->charset()->number;
4656
seg->length= keyinfo->key_part[i].length;
4657
seg->start= keyinfo->key_part[i].offset;
4658
if (key_field->flags & BLOB_FLAG)
4661
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4662
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4663
seg->bit_start= (uint8_t)(key_field->pack_length()
4664
- share->blob_ptr_size);
4665
seg->flag= HA_BLOB_PART;
4666
seg->length=0; // Whole blob in unique constraint
4670
seg->type= keyinfo->key_part[i].type;
4672
if (!(key_field->flags & NOT_NULL_FLAG))
4674
seg->null_bit= key_field->null_bit;
4675
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4677
We are using a GROUP BY on something that contains NULL
4678
In this case we have to tell MyISAM that two NULL should
4679
on INSERT be regarded at the same value
4681
if (!using_unique_constraint)
4682
keydef.flag|= HA_NULL_ARE_EQUAL;
4686
MI_CREATE_INFO create_info;
4687
memset(&create_info, 0, sizeof(create_info));
4689
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4691
create_info.data_file_length= ~(uint64_t) 0;
4693
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4694
(uint32_t) (*recinfo-start_recinfo),
4696
share->uniques, &uniquedef,
4698
HA_CREATE_TMP_TABLE)))
4700
file->print_error(error,MYF(0)); /* purecov: inspected */
4704
status_var_increment(in_use->status_var.created_tmp_disk_tables);
4705
share->db_record_offset= 1;
4712
void Table::free_tmp_table(Session *session)
4714
MEM_ROOT own_root= mem_root;
4715
const char *save_proc_info;
4717
save_proc_info=session->get_proc_info();
4718
session->set_proc_info("removing tmp table");
4720
// Release latches since this can take a long time
4721
ha_release_temporary_latches(session);
4726
file->ha_drop_table(s->table_name.str);
4728
file->ha_delete_table(s->table_name.str);
4733
for (Field **ptr= field ; *ptr ; ptr++)
4735
free_io_cache(this);
4737
if (temp_pool_slot != MY_BIT_NONE)
4738
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4740
plugin_unlock(0, s->db_plugin);
4742
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4743
session->set_proc_info(save_proc_info);
4749
If a HEAP table gets full, create a MyISAM table and copy all rows
4753
bool create_myisam_from_heap(Session *session, Table *table,
4754
MI_COLUMNDEF *start_recinfo,
4755
MI_COLUMNDEF **recinfo,
4756
int error, bool ignore_last_dupp_key_error)
4760
const char *save_proc_info;
4763
if (table->s->db_type() != heap_hton ||
4764
error != HA_ERR_RECORD_FILE_FULL)
4766
table->file->print_error(error,MYF(0));
4770
// Release latches since this can take a long time
4771
ha_release_temporary_latches(session);
4775
new_table.s= &share;
4776
new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4777
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4778
new_table.s->db_type())))
4779
return(1); // End of memory
4781
save_proc_info=session->get_proc_info();
4782
session->set_proc_info("converting HEAP to MyISAM");
4784
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4785
recinfo, session->lex->select_lex.options |
4788
if (new_table.open_tmp_table())
4790
if (table->file->indexes_are_disabled())
4791
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4792
table->file->ha_index_or_rnd_end();
4793
table->file->ha_rnd_init(1);
4796
new_table.file->extra(HA_EXTRA_NO_ROWS);
4797
new_table.no_rows=1;
4800
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4801
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4804
copy all old rows from heap table to MyISAM table
4805
This is the only code that uses record[1] to read/write but this
4806
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4808
while (!table->file->rnd_next(new_table.record[1]))
4810
write_err= new_table.file->ha_write_row(new_table.record[1]);
4814
/* copy row that filled HEAP table */
4815
if ((write_err=new_table.file->ha_write_row(table->record[0])))
4817
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4818
!ignore_last_dupp_key_error)
4822
/* remove heap table and change to use myisam table */
4823
(void) table->file->ha_rnd_end();
4824
(void) table->file->close(); // This deletes the table !
4827
plugin_unlock(0, table->s->db_plugin);
4828
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4829
new_table.s= table->s; // Keep old share
4833
table->file->change_table_ptr(table, table->s);
4834
table->use_all_columns();
4837
const char *new_proc_info=
4838
(!strcmp(save_proc_info,"Copying to tmp table") ?
4839
"Copying to tmp table on disk" : save_proc_info);
4840
session->set_proc_info(new_proc_info);
4845
table->file->print_error(write_err, MYF(0));
4846
(void) table->file->ha_rnd_end();
4847
(void) new_table.file->close();
4849
new_table.file->ha_delete_table(new_table.s->table_name.str);
4851
delete new_table.file;
4852
session->set_proc_info(save_proc_info);
4853
table->mem_root= new_table.mem_root;
4857
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4859
my_bitmap_map *old= bitmap->bitmap;
4860
bitmap->bitmap= s->all_set.bitmap;
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4864
void Table::restore_column_map(my_bitmap_map *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
4866
read_set->bitmap= old;
1436
4869
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1438
4871
uint32_t min_length= UINT32_MAX;
1439
4872
uint32_t best= MAX_KEY;
1440
if (usable_keys->any())
4873
if (!usable_keys->is_clear_all())
1442
for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
4875
for (uint32_t nr=0; nr < s->keys ; nr++)
1444
if (usable_keys->test(nr))
4877
if (usable_keys->is_set(nr))
1446
4879
if (key_info[nr].key_length < min_length)