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>
49
#include <drizzled/plugin/storage_engine.h>
38
#include <drizzled/serialize/table.pb.h>
51
40
#include <drizzled/item/string.h>
52
41
#include <drizzled/item/int.h>
53
42
#include <drizzled/item/decimal.h>
54
43
#include <drizzled/item/float.h>
55
44
#include <drizzled/item/null.h>
56
#include <drizzled/temporal.h>
58
#include <drizzled/refresh_version.h>
60
#include <drizzled/table/singular.h>
62
#include <drizzled/table_proto.h>
63
#include <drizzled/typelib.h>
65
47
using namespace std;
70
extern plugin::StorageEngine *heap_engine;
71
extern plugin::StorageEngine *myisam_engine;
73
/* Functions defined in this cursor */
49
/* Keyword for parsing virtual column functions */
50
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
52
/* Functions defined in this file */
54
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
55
myf errortype, int errarg);
56
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
57
uint32_t types, char **names);
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();
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)
411
LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
412
strlen(table.engine().name().c_str()) };
413
share->db_plugin= ha_resolve_by_name(session, &engine_name);
416
share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
418
drizzle::Table::TableOptions table_options;
420
if(table.has_options())
421
table_options= table.options();
423
uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
425
if(table_options.has_pack_keys())
427
if(table_options.pack_keys())
428
db_create_options|= HA_OPTION_PACK_KEYS;
430
db_create_options|= HA_OPTION_NO_PACK_KEYS;
433
if(table_options.pack_record())
434
db_create_options|= HA_OPTION_PACK_RECORD;
436
if(table_options.has_checksum())
438
if(table_options.checksum())
439
db_create_options|= HA_OPTION_CHECKSUM;
441
db_create_options|= HA_OPTION_NO_CHECKSUM;
444
if(table_options.has_delay_key_write())
446
if(table_options.delay_key_write())
447
db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
449
db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
452
/* db_create_options was stored as 2 bytes in FRM
453
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
455
share->db_create_options= (db_create_options & 0x0000FFFF);
456
share->db_options_in_use= share->db_create_options;
459
share->avg_row_length= table_options.has_avg_row_length() ?
460
table_options.avg_row_length() : 0;
462
share->page_checksum= table_options.has_page_checksum() ?
463
(table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
466
share->row_type= table_options.has_row_type() ?
467
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
469
share->block_size= table_options.has_block_size() ?
470
table_options.block_size() : 0;
472
share->table_charset= get_charset(table_options.has_collation_id()?
473
table_options.collation_id() : 0);
475
if (!share->table_charset)
477
/* unknown charset in head[38] or pre-3.23 frm */
478
if (use_mb(default_charset_info))
480
/* Warn that we may be changing the size of character columns */
481
errmsg_printf(ERRMSG_LVL_WARN,
482
_("'%s' had no or invalid character set, "
483
"and default character set is multi-byte, "
484
"so character column sizes may have changed"),
487
share->table_charset= default_charset_info;
490
share->db_record_offset= 1;
492
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
494
share->db_low_byte_first= true;
496
share->max_rows= table_options.has_max_rows() ?
497
table_options.max_rows() : 0;
499
share->min_rows= table_options.has_min_rows() ?
500
table_options.min_rows() : 0;
502
share->keys= table.indexes_size();
505
for(int indx= 0; indx < table.indexes_size(); indx++)
506
share->key_parts+= table.indexes(indx).index_part_size();
508
share->key_info= (KEY*) alloc_root(&share->mem_root,
509
table.indexes_size() * sizeof(KEY)
510
+share->key_parts*sizeof(KEY_PART_INFO));
512
KEY_PART_INFO *key_part;
514
key_part= reinterpret_cast<KEY_PART_INFO*>
515
(share->key_info+table.indexes_size());
518
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
519
sizeof(ulong*)*share->key_parts);
521
share->keynames.count= table.indexes_size();
522
share->keynames.name= NULL;
523
share->keynames.type_names= (const char**)
524
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
526
share->keynames.type_lengths= (unsigned int*)
527
alloc_root(&share->mem_root,
528
sizeof(unsigned int) * (table.indexes_size()+1));
530
share->keynames.type_names[share->keynames.count]= NULL;
531
share->keynames.type_lengths[share->keynames.count]= 0;
533
KEY* keyinfo= share->key_info;
534
for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
536
drizzle::Table::Index indx= table.indexes(keynr);
542
keyinfo->flags|= HA_NOSAME;
544
if(indx.has_options())
546
drizzle::Table::Index::IndexOptions indx_options= indx.options();
547
if(indx_options.pack_key())
548
keyinfo->flags|= HA_PACK_KEY;
550
if(indx_options.var_length_key())
551
keyinfo->flags|= HA_VAR_LENGTH_PART;
553
if(indx_options.null_part_key())
554
keyinfo->flags|= HA_NULL_PART_KEY;
556
if(indx_options.binary_pack_key())
557
keyinfo->flags|= HA_BINARY_PACK_KEY;
559
if(indx_options.has_partial_segments())
560
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
562
if(indx_options.auto_generated_key())
563
keyinfo->flags|= HA_GENERATED_KEY;
565
if(indx_options.has_key_block_size())
567
keyinfo->flags|= HA_USES_BLOCK_SIZE;
568
keyinfo->block_size= indx_options.key_block_size();
572
keyinfo->block_size= 0;
579
case drizzle::Table::Index::UNKNOWN_INDEX:
580
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
582
case drizzle::Table::Index::BTREE:
583
keyinfo->algorithm= HA_KEY_ALG_BTREE;
585
case drizzle::Table::Index::RTREE:
586
keyinfo->algorithm= HA_KEY_ALG_RTREE;
588
case drizzle::Table::Index::HASH:
589
keyinfo->algorithm= HA_KEY_ALG_HASH;
591
case drizzle::Table::Index::FULLTEXT:
592
keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
595
/* TODO: suitable warning ? */
596
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
600
keyinfo->key_length= indx.key_length();
602
keyinfo->key_parts= indx.index_part_size();
604
keyinfo->key_part= key_part;
605
keyinfo->rec_per_key= rec_per_key;
607
for(unsigned int partnr= 0;
608
partnr < keyinfo->key_parts;
609
partnr++, key_part++)
611
drizzle::Table::Index::IndexPart part;
612
part= indx.index_part(partnr);
616
key_part->field= NULL;
617
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
618
key_part->null_bit= 0;
619
/* key_part->null_offset is only set if null_bit (see later) */
620
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
621
/* key_part->type ???? */
622
key_part->key_part_flag= 0;
623
if(part.has_in_reverse_order())
624
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
626
key_part->length= part.compare_length();
628
key_part->store_length= key_part->length;
630
/* key_part->offset is set later */
631
key_part->key_type= part.key_type();
635
if(!indx.has_comment())
637
keyinfo->comment.length= 0;
638
keyinfo->comment.str= NULL;
642
keyinfo->flags|= HA_USES_COMMENT;
643
keyinfo->comment.length= indx.comment().length();
644
keyinfo->comment.str= strmake_root(&share->mem_root,
645
indx.comment().c_str(),
646
keyinfo->comment.length);
649
keyinfo->name= strmake_root(&share->mem_root,
651
indx.name().length());
653
share->keynames.type_names[keynr]= keyinfo->name;
654
share->keynames.type_lengths[keynr]= indx.name().length();
657
share->keys_for_keyread.init(0);
658
share->keys_in_use.init(share->keys);
660
if(table_options.has_connect_string())
662
size_t len= table_options.connect_string().length();
663
const char* str= table_options.connect_string().c_str();
665
share->connect_string.length= len;
666
share->connect_string.str= strmake_root(&share->mem_root, str, len);
669
if(table_options.has_comment())
671
size_t len= table_options.comment().length();
672
const char* str= table_options.comment().c_str();
674
share->comment.length= len;
675
share->comment.str= strmake_root(&share->mem_root, str, len);
678
share->key_block_size= table_options.has_key_block_size() ?
679
table_options.key_block_size() : 0;
681
share->fields= table.field_size();
683
share->stored_fields= share->fields;
685
share->field= (Field**) alloc_root(&share->mem_root,
686
((share->fields+1) * sizeof(Field*)));
687
share->field[share->fields]= NULL;
689
uint32_t null_fields= 0;
692
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
693
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
695
assert(field_offsets && field_pack_length); // TODO: fixme
697
uint32_t interval_count= 0;
698
uint32_t interval_parts= 0;
700
uint32_t stored_columns_reclength= 0;
702
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
704
drizzle::Table::Field pfield= table.field(fieldnr);
705
if(pfield.has_constraints() && pfield.constraints().is_nullable())
708
bool field_is_stored= true;
710
enum_field_types drizzle_field_type=
711
proto_field_type_to_drizzle_type(pfield.type());
713
if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
715
drizzle::Table::Field::VirtualFieldOptions field_options=
716
pfield.virtual_options();
718
drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
720
field_is_stored= field_options.physically_stored();
723
field_offsets[fieldnr]= stored_columns_reclength;
725
/* the below switch is very similar to
726
Create_field::create_length_to_internal_length in field.cc
727
(which should one day be replace by just this code)
729
switch(drizzle_field_type)
731
case DRIZZLE_TYPE_BLOB:
732
case DRIZZLE_TYPE_VARCHAR:
734
drizzle::Table::Field::StringFieldOptions field_options=
735
pfield.string_options();
737
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
738
field_options.collation_id() : 0);
741
cs= default_charset_info;
743
field_pack_length[fieldnr]=
744
calc_pack_length(drizzle_field_type,
745
field_options.length() * cs->mbmaxlen);
749
case DRIZZLE_TYPE_ENUM:
751
drizzle::Table::Field::SetFieldOptions field_options=
752
pfield.set_options();
754
field_pack_length[fieldnr]=
755
get_enum_pack_length(field_options.field_value_size());
758
interval_parts+= field_options.field_value_size();
761
case DRIZZLE_TYPE_NEWDECIMAL:
763
drizzle::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
765
field_pack_length[fieldnr]=
766
my_decimal_get_binary_size(fo.precision(), fo.scale());
770
/* Zero is okay here as length is fixed for other types. */
771
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
774
share->reclength+= field_pack_length[fieldnr];
777
stored_columns_reclength+= field_pack_length[fieldnr];
780
/* data_offset added to stored_rec_length later */
781
share->stored_rec_length= stored_columns_reclength;
783
/* fix up offsets for non-stored fields (at end of record) */
784
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
786
drizzle::Table::Field pfield= table.field(fieldnr);
788
bool field_is_stored= true;
790
enum_field_types drizzle_field_type=
791
proto_field_type_to_drizzle_type(pfield.type());
793
if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
795
drizzle::Table::Field::VirtualFieldOptions field_options=
796
pfield.virtual_options();
798
field_is_stored= field_options.physically_stored();
803
field_offsets[fieldnr]= stored_columns_reclength;
804
stored_columns_reclength+= field_pack_length[fieldnr];
807
share->null_fields= null_fields;
809
ulong null_bits= null_fields;
810
if(!table_options.pack_record())
812
ulong data_offset= (null_bits + 7)/8;
815
share->reclength+= data_offset;
816
share->stored_rec_length+= data_offset;
818
ulong rec_buff_length;
820
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
821
share->rec_buff_length= rec_buff_length;
823
unsigned char* record= NULL;
825
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
829
memset(record, 0, rec_buff_length);
833
if(!table_options.pack_record())
835
null_count++; // one bit for delete mark.
839
share->default_values= record;
843
share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
844
interval_count*sizeof(TYPELIB));
847
share->intervals= NULL;
849
share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
850
(share->fields+1)*sizeof(char*));
852
share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
853
(share->fields+1)*sizeof(unsigned int));
855
share->fieldnames.type_names[share->fields]= NULL;
856
share->fieldnames.type_lengths[share->fields]= 0;
857
share->fieldnames.count= share->fields;
860
/* Now fix the TYPELIBs for the intervals (enum values)
864
uint32_t interval_nr= 0;
866
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
868
drizzle::Table::Field pfield= table.field(fieldnr);
871
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
872
pfield.name().c_str(),
873
pfield.name().length());
875
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
878
if(pfield.type() != drizzle::Table::Field::ENUM)
881
drizzle::Table::Field::SetFieldOptions field_options=
882
pfield.set_options();
884
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
885
field_options.collation_id() : 0);
888
charset= default_charset_info;
890
TYPELIB *t= &(share->intervals[interval_nr]);
892
t->type_names= (const char**)alloc_root(&share->mem_root,
893
(field_options.field_value_size()+1)*sizeof(char*));
895
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
896
(field_options.field_value_size()+1)*sizeof(unsigned int));
898
t->type_names[field_options.field_value_size()]= NULL;
899
t->type_lengths[field_options.field_value_size()]= 0;
901
t->count= field_options.field_value_size();
904
for(int n=0; n < field_options.field_value_size(); n++)
906
t->type_names[n]= strmake_root(&share->mem_root,
907
field_options.field_value(n).c_str(),
908
field_options.field_value(n).length());
910
/* Go ask the charset what the length is as for "" length=1
911
and there's stripping spaces or some other crack going on.
914
lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
915
field_options.field_value(n).length());
916
t->type_lengths[n]= lengthsp;
922
/* and read the fields */
925
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
928
use_hash= !hash_init(&share->name_hash,
931
(hash_get_key) get_field_name, 0, 0);
933
unsigned char* null_pos= record;;
934
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
936
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
938
drizzle::Table::Field pfield= table.field(fieldnr);
940
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
942
switch(pfield.format())
944
case drizzle::Table::Field::DefaultFormat:
945
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
947
case drizzle::Table::Field::FixedFormat:
948
column_format= COLUMN_FORMAT_TYPE_FIXED;
950
case drizzle::Table::Field::DynamicFormat:
951
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
957
Field::utype unireg_type= Field::NONE;
959
if(pfield.has_numeric_options()
960
&& pfield.numeric_options().is_autoincrement())
962
unireg_type= Field::NEXT_NUMBER;
965
if(pfield.has_options()
966
&& pfield.options().has_default_value()
967
&& pfield.options().default_value().compare("NOW()")==0)
969
if(pfield.options().has_update_value()
970
&& pfield.options().update_value().compare("NOW()")==0)
972
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
974
else if (!pfield.options().has_update_value())
976
unireg_type= Field::TIMESTAMP_DN_FIELD;
979
assert(1); // Invalid update value.
981
else if (pfield.has_options()
982
&& pfield.options().has_update_value()
983
&& pfield.options().update_value().compare("NOW()")==0)
985
unireg_type= Field::TIMESTAMP_UN_FIELD;
989
if(!pfield.has_comment())
991
comment.str= (char*)"";
996
size_t len= pfield.comment().length();
997
const char* str= pfield.comment().c_str();
999
comment.str= strmake_root(&share->mem_root, str, len);
1000
comment.length= len;
1003
enum_field_types field_type;
1004
virtual_column_info *vcol_info= NULL;
1005
bool field_is_stored= true;
1008
field_type= proto_field_type_to_drizzle_type(pfield.type());
1010
if(field_type==DRIZZLE_TYPE_VIRTUAL)
1012
drizzle::Table::Field::VirtualFieldOptions field_options=
1013
pfield.virtual_options();
1015
vcol_info= new virtual_column_info();
1016
field_type= proto_field_type_to_drizzle_type(field_options.type());
1017
field_is_stored= field_options.physically_stored();
1019
size_t len= field_options.expression().length();
1020
const char* str= field_options.expression().c_str();
1022
vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
1023
vcol_info->expr_str.length= len;
1028
const CHARSET_INFO *charset= &my_charset_bin;
1030
if(field_type==DRIZZLE_TYPE_BLOB
1031
|| field_type==DRIZZLE_TYPE_VARCHAR)
1033
drizzle::Table::Field::StringFieldOptions field_options=
1034
pfield.string_options();
1036
charset= get_charset(field_options.has_collation_id()?
1037
field_options.collation_id() : 0);
1040
charset= default_charset_info;
1044
if(field_type==DRIZZLE_TYPE_ENUM)
1046
drizzle::Table::Field::SetFieldOptions field_options=
1047
pfield.set_options();
1049
charset= get_charset(field_options.has_collation_id()?
1050
field_options.collation_id() : 0);
1053
charset= default_charset_info;
1057
Item *default_value= NULL;
1059
if(pfield.options().has_default_value()
1060
|| pfield.options().has_default_null()
1061
|| pfield.options().has_default_bin_value())
1063
default_value= default_value_item(field_type,
1065
pfield.options().default_null(),
1066
pfield.options().default_value(),
1067
pfield.options().default_bin_value());
1070
uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
1072
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
1073
memset(&temp_table, 0, sizeof(temp_table));
1074
temp_table.s= share;
1075
temp_table.in_use= session;
1076
temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
1077
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
1079
Field* f= make_field(share, &share->mem_root,
1080
record+field_offsets[fieldnr]+data_offset,
1081
pfield.options().length(),
1087
(Field::utype) MTYP_TYPENR(unireg_type),
1088
((field_type==DRIZZLE_TYPE_ENUM)?
1089
share->intervals+(interval_nr++)
1091
share->fieldnames.type_names[fieldnr]);
1093
share->field[fieldnr]= f;
1095
f->init(&temp_table); /* blob default values need table obj */
1097
if(!(f->flags & NOT_NULL_FLAG))
1099
*f->null_ptr|= f->null_bit;
1100
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
1107
int res= default_value->save_in_field(f, 1);
1108
(void)res; // TODO error handle;
1110
else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
1111
(f->flags & NOT_NULL_FLAG))
1114
f->store((int64_t) 1, true);
1119
/* hack to undo f->init() */
1121
f->orig_table= NULL;
1123
f->field_index= fieldnr;
1124
f->comment= comment;
1125
f->vcol_info= vcol_info;
1126
f->is_stored= field_is_stored;
1128
&& !(f->unireg_check==Field::NEXT_NUMBER)
1129
&& (f->flags & NOT_NULL_FLAG)
1130
&& (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
1131
f->flags|= NO_DEFAULT_VALUE_FLAG;
1133
if(f->unireg_check == Field::NEXT_NUMBER)
1134
share->found_next_number_field= &(share->field[fieldnr]);
1136
if(share->timestamp_field == f)
1137
share->timestamp_field_offset= fieldnr;
1139
if (use_hash) /* supposedly this never fails... but comments lie */
1140
(void) my_hash_insert(&share->name_hash,
1141
(unsigned char*)&(share->field[fieldnr]));
1145
share->stored_fields--;
1149
keyinfo= share->key_info;
1150
for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
1152
key_part= keyinfo->key_part;
1154
for(unsigned int partnr= 0;
1155
partnr < keyinfo->key_parts;
1156
partnr++, key_part++)
1158
/* Fix up key_part->offset by adding data_offset.
1159
We really should compute offset as well.
1160
But at least this way we are a little better. */
1161
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1166
We need to set the unused bits to 1. If the number of bits is a multiple
1167
of 8 there are no unused bits.
1171
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1173
share->null_bytes= (null_pos - (unsigned char*) record +
1174
(null_bit_pos + 7) / 8);
1176
share->last_null_bit_pos= null_bit_pos;
1178
free(field_offsets);
1179
free(field_pack_length);
1181
handler *handler_file;
1183
if(!(handler_file= get_new_handler(share, session->mem_root,
1188
if (share->key_parts)
1190
uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
1191
&share->keynames, 3) - 1);
1193
int64_t ha_option= handler_file->ha_table_flags();
1195
keyinfo= share->key_info;
1196
key_part= keyinfo->key_part;
1198
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1200
uint32_t usable_parts= 0;
1202
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1205
If the UNIQUE key doesn't have NULL columns and is not a part key
1206
declare this as a primary key.
1209
for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
1211
uint32_t fieldnr= key_part[i].fieldnr;
1213
share->field[fieldnr-1]->null_ptr ||
1214
share->field[fieldnr-1]->key_length() !=
1217
primary_key=MAX_KEY; // Can't be used
1223
for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1226
if (!key_part->fieldnr)
1228
// error= 4; // Wrong file
1229
abort(); // goto err;
1231
field= key_part->field= share->field[key_part->fieldnr-1];
1232
key_part->type= field->key_type();
1233
if (field->null_ptr)
1235
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1236
share->default_values);
1237
key_part->null_bit= field->null_bit;
1238
key_part->store_length+=HA_KEY_NULL_LENGTH;
1239
keyinfo->flags|=HA_NULL_PART_KEY;
1240
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1241
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1243
if (field->type() == DRIZZLE_TYPE_BLOB ||
1244
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1246
if (field->type() == DRIZZLE_TYPE_BLOB)
1247
key_part->key_part_flag|= HA_BLOB_PART;
1249
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1250
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1251
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1252
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1254
if (i == 0 && key != primary_key)
1255
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1256
(keyinfo->key_parts == 1)) ?
1257
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1259
field->key_start.set_bit(key);
1260
if (field->key_length() == key_part->length &&
1261
!(field->flags & BLOB_FLAG))
1263
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1265
share->keys_for_keyread.set_bit(key);
1266
field->part_of_key.set_bit(key);
1267
field->part_of_key_not_clustered.set_bit(key);
1269
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1270
field->part_of_sortkey.set_bit(key);
1272
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1274
usable_parts++; // For FILESORT
1275
field->flags|= PART_KEY_FLAG;
1276
if (key == primary_key)
1278
field->flags|= PRI_KEY_FLAG;
1280
If this field is part of the primary key and all keys contains
1281
the primary key, then we can use any key to find this column
1283
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1285
field->part_of_key= share->keys_in_use;
1286
if (field->part_of_sortkey.is_set(key))
1287
field->part_of_sortkey= share->keys_in_use;
1290
if (field->key_length() != key_part->length)
1292
key_part->key_part_flag|= HA_PART_KEY_SEG;
1295
keyinfo->usable_key_parts= usable_parts; // Filesort
1297
set_if_bigger(share->max_key_length,keyinfo->key_length+
1298
keyinfo->key_parts);
1299
share->total_key_length+= keyinfo->key_length;
1301
MERGE tables do not have unique indexes. But every key could be
1302
an unique index on the underlying MyISAM table. (Bug #10400)
1304
if ((keyinfo->flags & HA_NOSAME) ||
1305
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1306
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1308
if (primary_key < MAX_KEY &&
1309
(share->keys_in_use.is_set(primary_key)))
1311
share->primary_key= primary_key;
1313
If we are using an integer as the primary key then allow the user to
1314
refer to it as '_rowid'
1316
if (share->key_info[primary_key].key_parts == 1)
1318
Field *field= share->key_info[primary_key].key_part[0].field;
1319
if (field && field->result_type() == INT_RESULT)
1321
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1322
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1329
share->primary_key = MAX_KEY; // we do not have a primary key
1332
share->primary_key= MAX_KEY;
1334
if (share->found_next_number_field)
1336
Field *reg_field= *share->found_next_number_field;
1337
if ((int) (share->next_number_index= (uint32_t)
1338
find_ref_key(share->key_info, share->keys,
1339
share->default_values, reg_field,
1340
&share->next_number_key_offset,
1341
&share->next_number_keypart)) < 0)
1343
/* Wrong field definition */
1348
reg_field->flags |= AUTO_INCREMENT_FLAG;
1351
if (share->blob_fields)
1356
/* Store offsets to blob fields to find them fast */
1357
if (!(share->blob_field= save=
1358
(uint*) alloc_root(&share->mem_root,
1359
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1361
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1363
if ((*ptr)->flags & BLOB_FLAG)
1368
share->db_low_byte_first= handler_file->low_byte_first();
1369
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1371
my_bitmap_map *bitmaps;
1373
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1374
share->column_bitmap_size)))
1376
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1377
bitmap_set_all(&share->all_set);
1379
delete handler_file;
1383
share->error= error;
1384
share->open_errno= my_errno;
1386
hash_free(&share->name_hash);
1387
delete handler_file;
1388
open_table_error(share, error, share->open_errno, 0);
1393
Read table definition from a binary / text based .frm file
1397
session Thread handler
1398
share Fill this with table definition
1399
db_flags Bit mask of the following flags: OPEN_VIEW
1402
This function is called when the table definition is not cached in
1404
The data is returned in 'share', which is alloced by
1405
alloc_table_share().. The code assumes that share is initialized.
1409
1 Error (see open_table_error)
1410
2 Error (see open_table_error)
1411
3 Wrong data in .frm file
1412
4 Error (see open_table_error)
1413
5 Error (see open_table_error: charset unavailable)
1414
6 Unknown .frm version
1417
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
1426
path.reserve(FN_REFLEN);
1427
path.append(share->normalized_path.str);
1428
string proto_path= path;
1430
path.append(reg_ext);
1432
proto_path.append(".dfe");
1434
drizzle::Table table;
1436
if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
1445
if(!table.IsInitialized())
1453
parse_table_proto(session, table, share);
1455
share->table_category= get_table_category(& share->db, & share->table_name);
1458
session->status_var.opened_shares++;
1461
if (error && !error_given)
1463
share->error= error;
1464
open_table_error(share, error, (share->open_errno= my_errno), 0);
1471
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1472
This routine is used for error handling purposes.
1476
table Table object for which virtual columns are set-up
1481
static void clear_field_flag(Table *table)
1485
for (ptr= table->field; *ptr; ptr++)
1486
(*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1490
The function uses the feature in fix_fields where the flag
1491
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1492
This field must always be reset before returning from the function
1493
since it is used for other purposes as well.
1496
fix_fields_vcol_func()
1497
session The thread object
1498
func_item The item tree reference of the virtual columnfunction
1499
table The table object
1500
field_name The name of the processed field
1503
true An error occurred, something was wrong with the
1505
false Ok, a partition field array was created
1508
bool fix_fields_vcol_func(Session *session,
1511
const char *field_name)
1513
uint32_t dir_length, home_dir_length;
1516
TableList *save_table_list, *save_first_table, *save_last_table;
1518
Name_resolution_context *context;
1519
const char *save_where;
1521
char db_name_string[FN_REFLEN];
1522
bool save_use_only_table_context;
1523
Field **ptr, *field;
1524
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1528
Set-up the TABLE_LIST object to be a list with a single table
1529
Set the object to zero to create NULL pointers and set alias
1530
and real name to table name and get database name from file name.
1533
bzero((void*)&tables, sizeof(TableList));
1534
tables.alias= tables.table_name= (char*) table->s->table_name.str;
1535
tables.table= table;
1536
tables.next_local= NULL;
1537
tables.next_name_resolution_table= NULL;
1538
memcpy(db_name_string,
1539
table->s->normalized_path.str,
1540
table->s->normalized_path.length);
1541
db_name_string[table->s->normalized_path.length]= '\0';
1542
dir_length= dirname_length(db_name_string);
1543
db_name_string[dir_length - 1]= 0;
1544
home_dir_length= dirname_length(db_name_string);
1545
db_name= &db_name_string[home_dir_length];
1548
session->mark_used_columns= MARK_COLUMNS_NONE;
1550
context= session->lex->current_context();
1551
table->map= 1; //To ensure correct calculation of const item
1552
table->get_fields_in_item_tree= true;
1553
save_table_list= context->table_list;
1554
save_first_table= context->first_name_resolution_table;
1555
save_last_table= context->last_name_resolution_table;
1556
context->table_list= &tables;
1557
context->first_name_resolution_table= &tables;
1558
context->last_name_resolution_table= NULL;
1559
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1560
save_where= session->where;
1561
session->where= "virtual column function";
1563
/* Save the context before fixing the fields*/
1564
save_use_only_table_context= session->lex->use_only_table_context;
1565
session->lex->use_only_table_context= true;
1566
/* Fix fields referenced to by the virtual column function */
1567
error= func_expr->fix_fields(session, (Item**)0);
1568
/* Restore the original context*/
1569
session->lex->use_only_table_context= save_use_only_table_context;
1570
context->table_list= save_table_list;
1571
context->first_name_resolution_table= save_first_table;
1572
context->last_name_resolution_table= save_last_table;
1574
if (unlikely(error))
1576
clear_field_flag(table);
1579
session->where= save_where;
1581
Walk through the Item tree checking if all items are valid
1582
to be part of the virtual column
1584
error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1587
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1588
clear_field_flag(table);
1591
if (unlikely(func_expr->const_item()))
1593
my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1594
clear_field_flag(table);
1597
/* Ensure that this virtual column is not based on another virtual field. */
1599
while ((field= *(ptr++)))
1601
if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1604
my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1605
clear_field_flag(table);
1610
Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1611
when calling fix_fields.
1613
clear_field_flag(table);
1617
table->get_fields_in_item_tree= false;
1618
session->mark_used_columns= save_mark_used_columns;
1619
table->map= 0; //Restore old value
1624
Unpack the definition of a virtual column
1627
unpack_vcol_info_from_frm()
1628
session Thread handler
1629
table Table with the checked field
1630
field Pointer to Field object
1631
open_mode Open table mode needed to determine
1632
which errors need to be generated in a failure
1633
error_reported updated flag for the caller that no other error
1634
messages are to be generated.
1640
bool unpack_vcol_info_from_frm(Session *session,
1643
LEX_STRING *vcol_expr,
1644
open_table_mode open_mode,
1645
bool *error_reported)
1650
Step 1: Construct a statement for the parser.
1651
The parsed string needs to take the following format:
1652
"PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1654
char *vcol_expr_str;
1657
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1659
parse_vcol_keyword.length + 3)))
1663
memcpy(vcol_expr_str,
1664
(char*) parse_vcol_keyword.str,
1665
parse_vcol_keyword.length);
1666
str_len= parse_vcol_keyword.length;
1667
memcpy(vcol_expr_str + str_len, "(", 1);
1669
memcpy(vcol_expr_str + str_len,
1670
(char*) vcol_expr->str,
1672
str_len+= vcol_expr->length;
1673
memcpy(vcol_expr_str + str_len, ")", 1);
1675
memcpy(vcol_expr_str + str_len, "\0", 1);
1677
Lex_input_stream lip(session, vcol_expr_str, str_len);
1680
Step 2: Setup session for parsing.
1681
1) make Item objects be created in the memory allocated for the Table
1682
object (not TABLE_SHARE)
1683
2) ensure that created Item's are not put on to session->free_list
1684
(which is associated with the parsed statement and hence cleared after
1686
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1687
to be parsed as a SQL command.
1689
MEM_ROOT **root_ptr, *old_root;
1690
Item *backup_free_list= session->free_list;
1691
root_ptr= current_mem_root_ptr();
1692
old_root= *root_ptr;
1693
*root_ptr= &table->mem_root;
1694
session->free_list= NULL;
1695
session->lex->parse_vcol_expr= true;
1698
Step 3: Use the parser to build an Item object from.
1700
if (parse_sql(session, &lip))
1704
/* From now on use vcol_info generated by the parser. */
1705
field->vcol_info= session->lex->vcol_info;
1707
/* Validate the Item tree. */
1708
if (fix_fields_vcol_func(session,
1709
field->vcol_info->expr_item,
1713
if (open_mode == OTM_CREATE)
1716
During CREATE/ALTER TABLE it is ok to receive errors here.
1717
It is not ok if it happens during the opening of an frm
1718
file as part of a normal query.
1720
*error_reported= true;
1722
field->vcol_info= NULL;
1725
field->vcol_info->item_free_list= session->free_list;
1726
session->free_list= backup_free_list;
1727
*root_ptr= old_root;
1732
session->lex->parse_vcol_expr= false;
1733
session->free_items();
1734
*root_ptr= old_root;
1735
session->free_list= backup_free_list;
1741
Open a table based on a TABLE_SHARE
1744
open_table_from_share()
1745
session Thread handler
1746
share Table definition
1747
alias Alias for table
1748
db_stat open flags (for example HA_OPEN_KEYFILE|
1749
HA_OPEN_RNDFILE..) can be 0 (example in
1751
prgflag READ_ALL etc..
1752
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1753
outparam result table
1754
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1755
if OTM_CREATE some errors are ignore
1756
if OTM_ALTER HA_OPEN is not called
1760
1 Error (see open_table_error)
1761
2 Error (see open_table_error)
1762
3 Wrong data in .frm file
1763
4 Error (see open_table_error)
1764
5 Error (see open_table_error: charset unavailable)
1765
7 Table definition has changed in engine
1768
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1769
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1770
Table *outparam, open_table_mode open_mode)
1773
uint32_t records, i, bitmap_size;
1774
bool error_reported= false;
1775
unsigned char *record, *bitmaps;
1776
Field **field_ptr, **vfield_ptr;
1778
/* Parsing of partitioning information from .frm needs session->lex set up. */
1779
assert(session->lex->is_lex_started);
1782
memset(outparam, 0, sizeof(*outparam));
1783
outparam->in_use= session;
1785
outparam->db_stat= db_stat;
1786
outparam->write_row_record= NULL;
1788
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1790
if (!(outparam->alias= strdup(alias)))
1792
outparam->quick_keys.init();
1793
outparam->covering_keys.init();
1794
outparam->keys_in_use_for_query.init();
1796
/* Allocate handler */
1798
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1800
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1810
outparam->reginfo.lock_type= TL_UNLOCK;
1811
outparam->current_lock= F_UNLCK;
1813
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1815
if (prgflag & (READ_ALL+EXTRA_RECORD))
1818
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1819
share->rec_buff_length * records)))
1820
goto err; /* purecov: inspected */
1824
/* We are probably in hard repair, and the buffers should not be used */
1825
outparam->record[0]= outparam->record[1]= share->default_values;
1829
outparam->record[0]= record;
1831
outparam->record[1]= record+ share->rec_buff_length;
1833
outparam->record[1]= outparam->record[0]; // Safety
1838
We need this because when we read var-length rows, we are not updating
1839
bytes after end of varchar
1843
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1844
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1846
memcpy(outparam->record[1], share->default_values,
1847
share->rec_buff_length);
1851
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1852
(uint32_t) ((share->fields+1)*
1854
goto err; /* purecov: inspected */
1856
outparam->field= field_ptr;
1858
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1860
outparam->null_flags= (unsigned char*) record+1;
1862
/* Setup copy of fields from share, but use the right alias and record */
1863
for (i=0 ; i < share->fields; i++, field_ptr++)
1865
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1868
(*field_ptr)= 0; // End marker
1870
if (share->found_next_number_field)
1871
outparam->found_next_number_field=
1872
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1873
if (share->timestamp_field)
1874
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1877
/* Fix key->name and key_part->field */
1878
if (share->key_parts)
1880
KEY *key_info, *key_info_end;
1881
KEY_PART_INFO *key_part;
1883
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1884
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1886
outparam->key_info= key_info;
1887
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1889
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1890
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1893
for (key_info_end= key_info + share->keys ;
1894
key_info < key_info_end ;
1897
KEY_PART_INFO *key_part_end;
1899
key_info->table= outparam;
1900
key_info->key_part= key_part;
1902
for (key_part_end= key_part+ key_info->key_parts ;
1903
key_part < key_part_end ;
1906
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1908
if (field->key_length() != key_part->length &&
1909
!(field->flags & BLOB_FLAG))
1912
We are using only a prefix of the column as a key:
1913
Create a new field for the key part that matches the index
1915
field= key_part->field=field->new_field(&outparam->mem_root,
1917
field->field_length= key_part->length;
1924
Process virtual columns, if any.
1926
if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
1927
(uint32_t) ((share->vfields+1)*
1931
outparam->vfield= vfield_ptr;
1933
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
1935
if ((*field_ptr)->vcol_info)
1937
if (unpack_vcol_info_from_frm(session,
1940
&(*field_ptr)->vcol_info->expr_str,
1944
error= 4; // in case no error is reported
1947
*(vfield_ptr++)= *field_ptr;
1950
*vfield_ptr= NULL; // End marker
1951
/* Check virtual columns against table's storage engine. */
1952
if ((share->vfields && outparam->file) &&
1953
(not outparam->file->check_if_supported_virtual_columns()))
1955
my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
1957
"Specified storage engine");
1958
error_reported= true;
1962
/* Allocate bitmaps */
1964
bitmap_size= share->column_bitmap_size;
1965
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1967
bitmap_init(&outparam->def_read_set,
1968
(my_bitmap_map*) bitmaps, share->fields, false);
1969
bitmap_init(&outparam->def_write_set,
1970
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1971
bitmap_init(&outparam->tmp_set,
1972
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1973
outparam->default_column_bitmaps();
1975
/* The table struct is now initialized; Open the table */
1977
if (db_stat && open_mode != OTM_ALTER)
1980
if ((ha_err= (outparam->file->
1981
ha_open(outparam, share->normalized_path.str,
1982
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1983
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1984
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1985
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1986
HA_OPEN_ABORT_IF_LOCKED :
1987
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1989
/* Set a flag if the table is crashed and it can be auto. repaired */
1990
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1991
outparam->file->auto_repair() &&
1992
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1996
case HA_ERR_NO_SUCH_TABLE:
1998
The table did not exists in storage engine, use same error message
1999
as if the .frm file didn't exist
2006
Too many files opened, use same error message as if the .frm
2013
outparam->file->print_error(ha_err, MYF(0));
2014
error_reported= true;
2015
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
2019
goto err; /* purecov: inspected */
2023
#if defined(HAVE_purify)
2024
memset(bitmaps, 0, bitmap_size*3);
2027
outparam->no_replicate= outparam->file;
2028
session->status_var.opened_tables++;
2033
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
2034
open_table_error(share, error, my_errno, 0);
2035
delete outparam->file;
2036
outparam->file= 0; // For easier error checking
2037
outparam->db_stat=0;
2038
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
2039
free((char*) outparam->alias);
2043
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
2044
uint32_t Table::tmpkeyval()
2046
return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
2050
Free information allocated by openfrm
2054
table Table object to free
2055
free_share Is 1 if we also want to free table_share
2058
int Table::closefrm(bool free_share)
83
error= cursor->close();
2063
error= file->close();
2064
free((char*) alias);
88
2068
for (Field **ptr=field ; *ptr ; ptr++)
2073
file= 0; /* For easier errorchecking */
2076
if (s->tmp_table == NO_TMP_TABLE)
2077
release_table_share(s, RELEASE_NORMAL);
2079
free_table_share(s);
2081
free_root(&mem_root, MYF(0));
106
mem_root.free_root(MYF(0));
110
void Table::resetTable(Session *session,
112
uint32_t db_stat_arg)
127
db_stat= db_stat_arg;
129
record[0]= (unsigned char *) NULL;
130
record[1]= (unsigned char *) NULL;
132
insert_values.clear();
134
next_number_field= NULL;
135
found_next_number_field= NULL;
136
timestamp_field= NULL;
138
pos_in_table_list= NULL;
148
derived_select_number= 0;
149
current_lock= F_UNLCK;
163
open_placeholder= false;
164
locked_by_name= false;
167
auto_increment_field_not_null= false;
168
alias_name_used= false;
171
quick_condition_rows= 0;
173
timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
178
covering_keys.reset();
183
keys_in_use_for_query.reset();
184
keys_in_use_for_group_by.reset();
185
keys_in_use_for_order_by.reset();
187
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
188
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
190
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
191
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
193
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
198
2087
/* Deallocate temporary blob storage */
200
void free_blobs(Table *table)
2089
void free_blobs(register Table *table)
202
2091
uint32_t *ptr, *end;
203
2092
for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
207
((Field_blob*) table->getField(*ptr))->free();
212
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
214
TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
2095
((Field_blob*) table->field[*ptr])->free();
2099
/* Find where a form starts */
2100
/* if formname is NULL then only formnames is read */
2102
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
2104
uint32_t a_length,names,length;
2105
unsigned char *pos,*buf;
2108
names=uint2korr(head+8);
2109
a_length=(names+2)*sizeof(char *); /* Room for two extra */
2114
save_names->type_names=0; /* Clear if error */
2118
length=uint2korr(head+4);
2119
lseek(file,64,SEEK_SET);
2120
if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
2121
my_read(file, buf+a_length, (size_t) (length+names*4),
2123
{ /* purecov: inspected */
2126
return(0L); /* purecov: inspected */
2128
pos= buf+a_length+length;
2129
ret_value=uint4korr(pos);
2134
free((unsigned char*) buf);
2137
memset(save_names, 0, sizeof(save_names));
2141
str=(char *) (buf+a_length);
2142
fix_type_pointers((const char ***) &buf,save_names,1,&str);
2149
Read string from a file with malloc
2152
We add an \0 at end of the read string to make reading of C strings easier
2155
int read_string(File file, unsigned char**to, size_t length)
2160
if (!(*to= (unsigned char*) malloc(length+1)) ||
2161
my_read(file, *to, length,MYF(MY_NABP)))
2166
return(1); /* purecov: inspected */
2168
*((char*) *to+length)= '\0';
2173
/* Add a new form to a form file */
2175
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
2176
const char *newname)
2178
uint32_t i,bufflength,maxlength,n_length,length,names;
2179
off_t endpos,newpos;
2180
unsigned char buff[IO_SIZE];
2183
length=(uint32_t) strlen(newname)+1;
2184
n_length=uint2korr(fileinfo+4);
2185
maxlength=uint2korr(fileinfo+6);
2186
names=uint2korr(fileinfo+8);
2187
newpos=uint4korr(fileinfo+10);
2189
if (64+length+n_length+(names+1)*4 > maxlength)
2192
int4store(fileinfo+10,newpos);
2193
endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
2194
bufflength= (uint32_t) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */
2196
while (endpos > maxlength)
2198
lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
2199
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
2201
lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
2202
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
2204
endpos-=bufflength; bufflength=IO_SIZE;
2206
memset(buff, 0, IO_SIZE); /* Null new block */
2207
lseek(file,(ulong) maxlength,SEEK_SET);
2208
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
2210
maxlength+=IO_SIZE; /* Fix old ref */
2211
int2store(fileinfo+6,maxlength);
2212
for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
2215
endpos=uint4korr(pos)+IO_SIZE;
2216
int4store(pos,endpos);
2223
sprintf((char*)buff,"/%s/",newname);
2226
sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
2227
lseek(file, 63 + n_length,SEEK_SET);
2228
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
2229
(names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
2230
names*4, MYF(MY_NABP+MY_WME))) ||
2231
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
2232
return(0L); /* purecov: inspected */
2234
int2store(fileinfo+8,names+1);
2235
int2store(fileinfo+4,n_length+length);
2236
assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
2238
} /* make_new_entry */
2241
/* error message when opening a form file */
2243
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
2246
char buff[FN_REFLEN];
2247
myf errortype= ME_ERROR+ME_WAITTANG;
2252
if (db_errno == ENOENT)
2253
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
2256
sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
2257
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
2258
errortype, buff, db_errno);
2264
const char *datext= "";
2266
if (share->db_type() != NULL)
2268
if ((file= get_new_handler(share, current_session->mem_root,
2271
if (!(datext= *file->bas_ext()))
2275
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
2276
ER_FILE_USED : ER_CANT_OPEN_FILE;
2277
sprintf(buff,"%s%s", share->normalized_path.str,datext);
2278
my_error(err_no,errortype, buff, db_errno);
2284
const char *csname= get_charset_name((uint32_t) errarg);
2286
if (!csname || csname[0] =='?')
2288
snprintf(tmp, sizeof(tmp), "#%d", errarg);
2291
my_printf_error(ER_UNKNOWN_COLLATION,
2292
_("Unknown collation '%s' in table '%-.64s' definition"),
2293
MYF(0), csname, share->table_name.str);
2297
sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
2298
my_printf_error(ER_NOT_FORM_FILE,
2299
_("Table '%-.64s' was created with a different version "
2300
"of Drizzle and cannot be read"),
2305
default: /* Better wrong error than none */
2307
sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
2308
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
2312
} /* open_table_error */
2316
** fix a str_type to a array type
2317
** typeparts separated with some char. differents types are separated
2322
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
2325
char *type_name, *ptr;
2331
point_to_type->name=0;
2332
point_to_type->type_names= *array;
2334
if ((chr= *ptr)) /* Test if empty type */
2336
while ((type_name=strchr(ptr+1,chr)) != NULL)
2338
*((*array)++) = ptr+1;
2339
*type_name= '\0'; /* End string */
2342
ptr+=2; /* Skip end mark and last 0 */
2346
point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
2348
*((*array)++)= NULL; /* End of type */
2350
*names=ptr; /* Update end */
2352
} /* fix_type_pointers */
2355
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
2357
TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
217
result->count= strings.elements;
2360
result->count=strings.elements;
219
2362
uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
221
if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
2363
if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
224
2365
result->type_lengths= (uint*) (result->type_names + result->count + 1);
226
List<String>::iterator it(strings.begin());
2366
List_iterator<String> it(strings);
228
for (uint32_t i= 0; (tmp= it++); i++)
2368
for (uint32_t i=0; (tmp=it++) ; i++)
230
2370
result->type_names[i]= tmp->ptr();
231
2371
result->type_lengths[i]= tmp->length();
234
result->type_names[result->count]= 0; // End marker
2373
result->type_names[result->count]= 0; // End marker
235
2374
result->type_lengths[result->count]= 0;
240
2378
/* Check that the integer is in the internal */
242
int set_zone(int nr, int min_zone, int max_zone)
2380
int set_zone(register int nr, int min_zone, int max_zone)
244
2382
if (nr<=min_zone)
245
2383
return (min_zone);
1376
4535
session->mem_root= mem_root_save;
4536
table->free_tmp_table(session); /* purecov: inspected */
4537
if (temp_pool_slot != MY_BIT_NONE)
4538
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4539
return(NULL); /* purecov: inspected */
1382
4542
/****************************************************************************/
1384
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1385
boost::dynamic_bitset<>& write_set_arg)
1387
read_set= &read_set_arg;
1388
write_set= &write_set_arg;
1392
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1394
const boost::dynamic_bitset<> old= in_map;
1395
in_map= getShare()->all_set;
4545
Create a reduced Table object with properly set up Field list from a
4546
list of field definitions.
4548
The created table doesn't have a table handler associated with
4549
it, has no keys, no group/distinct, no copy_funcs array.
4550
The sole purpose of this Table object is to use the power of Field
4551
class to read/write data to/from table->record[0]. Then one can store
4552
the record in any container (RB tree, hash, etc).
4553
The table is created in Session mem_root, so are the table's fields.
4554
Consequently, if you don't BLOB fields, you don't need to free it.
4556
@param session connection handle
4557
@param field_list list of column definitions
4560
0 if out of memory, Table object in case of success
4563
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4565
uint32_t field_count= field_list.elements;
4566
uint32_t blob_count= 0;
4568
Create_field *cdef; /* column definition */
4569
uint32_t record_length= 0;
4570
uint32_t null_count= 0; /* number of columns which may be null */
4571
uint32_t null_pack_length; /* NULL representation array length */
4572
uint32_t *blob_field;
4573
unsigned char *bitmaps;
4577
if (!multi_alloc_root(session->mem_root,
4578
&table, sizeof(*table),
4579
&share, sizeof(*share),
4580
&field, (field_count + 1) * sizeof(Field*),
4581
&blob_field, (field_count+1) *sizeof(uint32_t),
4582
&bitmaps, bitmap_buffer_size(field_count)*2,
4586
memset(table, 0, sizeof(*table));
4587
memset(share, 0, sizeof(*share));
4588
table->field= field;
4590
share->blob_field= blob_field;
4591
share->fields= field_count;
4592
share->blob_ptr_size= portable_sizeof_char_ptr;
4593
table->setup_tmp_table_column_bitmaps(bitmaps);
4595
/* Create all fields and calculate the total length of record */
4596
List_iterator_fast<Create_field> it(field_list);
4597
while ((cdef= it++))
4599
*field= make_field(share, NULL, 0, cdef->length,
4600
(unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4601
f_maybe_null(cdef->pack_flag) ? 1 : 0,
4602
cdef->pack_flag, cdef->sql_type, cdef->charset,
4604
cdef->interval, cdef->field_name);
4607
(*field)->init(table);
4608
record_length+= (*field)->pack_length();
4609
if (! ((*field)->flags & NOT_NULL_FLAG))
4612
if ((*field)->flags & BLOB_FLAG)
4613
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4617
*field= NULL; /* mark the end of the list */
4618
share->blob_field[blob_count]= 0; /* mark the end of the list */
4619
share->blob_fields= blob_count;
4621
null_pack_length= (null_count + 7)/8;
4622
share->reclength= record_length + null_pack_length;
4623
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4624
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4625
if (!table->record[0])
4628
if (null_pack_length)
4630
table->null_flags= (unsigned char*) table->record[0];
4631
share->null_fields= null_count;
4632
share->null_bytes= null_pack_length;
4635
table->in_use= session; /* field->reset() may access table->in_use */
4637
/* Set up field pointers */
4638
unsigned char *null_pos= table->record[0];
4639
unsigned char *field_pos= null_pos + share->null_bytes;
4640
uint32_t null_bit= 1;
4642
for (field= table->field; *field; ++field)
4644
Field *cur_field= *field;
4645
if ((cur_field->flags & NOT_NULL_FLAG))
4646
cur_field->move_field(field_pos);
4649
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
4651
if (null_bit == (1 << 8))
4659
field_pos+= cur_field->pack_length();
4664
for (field= table->field; *field; ++field)
4665
delete *field; /* just invokes field destructor */
4670
bool Table::open_tmp_table()
4673
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4674
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4676
file->print_error(error,MYF(0)); /* purecov: inspected */
4680
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
4686
Create MyISAM temporary table
4689
create_myisam_tmp_table()
4690
keyinfo Description of the index (there is always one index)
4691
start_recinfo MyISAM's column descriptions
4692
recinfo INOUT End of MyISAM's column descriptions
4696
Create a MyISAM temporary table according to passed description. The is
4697
assumed to have one unique index or constraint.
4699
The passed array or MI_COLUMNDEF structures must have this form:
4701
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4702
when there are many nullable columns)
4704
3. One free MI_COLUMNDEF element (*recinfo points here)
4706
This function may use the free element to create hash column for unique
4714
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4715
MI_COLUMNDEF *start_recinfo,
4716
MI_COLUMNDEF **recinfo,
4721
MI_UNIQUEDEF uniquedef;
4722
TABLE_SHARE *share= s;
4725
{ // Get keys for ni_create
4726
bool using_unique_constraint=0;
4727
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4728
sizeof(*seg) * keyinfo->key_parts);
4732
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4733
if (keyinfo->key_length >= file->max_key_length() ||
4734
keyinfo->key_parts > file->max_key_parts() ||
4737
/* Can't create a key; Make a unique constraint instead of a key */
4740
using_unique_constraint=1;
4741
memset(&uniquedef, 0, sizeof(uniquedef));
4742
uniquedef.keysegs=keyinfo->key_parts;
4744
uniquedef.null_are_equal=1;
4746
/* Create extra column for hash value */
4747
memset(*recinfo, 0, sizeof(**recinfo));
4748
(*recinfo)->type= FIELD_CHECK;
4749
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4751
share->reclength+=MI_UNIQUE_HASH_LENGTH;
4755
/* Create an unique key */
4756
memset(&keydef, 0, sizeof(keydef));
4757
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4758
keydef.keysegs= keyinfo->key_parts;
4761
for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4763
Field *key_field=keyinfo->key_part[i].field;
4765
seg->language= key_field->charset()->number;
4766
seg->length= keyinfo->key_part[i].length;
4767
seg->start= keyinfo->key_part[i].offset;
4768
if (key_field->flags & BLOB_FLAG)
4771
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4772
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4773
seg->bit_start= (uint8_t)(key_field->pack_length()
4774
- share->blob_ptr_size);
4775
seg->flag= HA_BLOB_PART;
4776
seg->length=0; // Whole blob in unique constraint
4780
seg->type= keyinfo->key_part[i].type;
4782
if (!(key_field->flags & NOT_NULL_FLAG))
4784
seg->null_bit= key_field->null_bit;
4785
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4787
We are using a GROUP BY on something that contains NULL
4788
In this case we have to tell MyISAM that two NULL should
4789
on INSERT be regarded at the same value
4791
if (!using_unique_constraint)
4792
keydef.flag|= HA_NULL_ARE_EQUAL;
4796
MI_CREATE_INFO create_info;
4797
memset(&create_info, 0, sizeof(create_info));
4799
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4801
create_info.data_file_length= ~(uint64_t) 0;
4803
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4804
(uint32_t) (*recinfo-start_recinfo),
4806
share->uniques, &uniquedef,
4808
HA_CREATE_TMP_TABLE)))
4810
file->print_error(error,MYF(0)); /* purecov: inspected */
4814
status_var_increment(in_use->status_var.created_tmp_disk_tables);
4815
share->db_record_offset= 1;
4822
void Table::free_tmp_table(Session *session)
4824
MEM_ROOT own_root= mem_root;
4825
const char *save_proc_info;
4827
save_proc_info=session->get_proc_info();
4828
session->set_proc_info("removing tmp table");
4830
// Release latches since this can take a long time
4831
ha_release_temporary_latches(session);
4836
file->ha_drop_table(s->table_name.str);
4838
file->ha_delete_table(s->table_name.str);
4843
for (Field **ptr= field ; *ptr ; ptr++)
4845
free_io_cache(this);
4847
if (temp_pool_slot != MY_BIT_NONE)
4848
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4850
plugin_unlock(0, s->db_plugin);
4852
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4853
session->set_proc_info(save_proc_info);
4859
If a HEAP table gets full, create a MyISAM table and copy all rows
4863
bool create_myisam_from_heap(Session *session, Table *table,
4864
MI_COLUMNDEF *start_recinfo,
4865
MI_COLUMNDEF **recinfo,
4866
int error, bool ignore_last_dupp_key_error)
4870
const char *save_proc_info;
4873
if (table->s->db_type() != heap_hton ||
4874
error != HA_ERR_RECORD_FILE_FULL)
4876
table->file->print_error(error,MYF(0));
4880
// Release latches since this can take a long time
4881
ha_release_temporary_latches(session);
4885
new_table.s= &share;
4886
new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4887
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4888
new_table.s->db_type())))
4889
return(1); // End of memory
4891
save_proc_info=session->get_proc_info();
4892
session->set_proc_info("converting HEAP to MyISAM");
4894
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4895
recinfo, session->lex->select_lex.options |
4898
if (new_table.open_tmp_table())
4900
if (table->file->indexes_are_disabled())
4901
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4902
table->file->ha_index_or_rnd_end();
4903
table->file->ha_rnd_init(1);
4906
new_table.file->extra(HA_EXTRA_NO_ROWS);
4907
new_table.no_rows=1;
4910
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4911
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4914
copy all old rows from heap table to MyISAM table
4915
This is the only code that uses record[1] to read/write but this
4916
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4918
while (!table->file->rnd_next(new_table.record[1]))
4920
write_err= new_table.file->ha_write_row(new_table.record[1]);
4924
/* copy row that filled HEAP table */
4925
if ((write_err=new_table.file->ha_write_row(table->record[0])))
4927
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4928
!ignore_last_dupp_key_error)
4932
/* remove heap table and change to use myisam table */
4933
(void) table->file->ha_rnd_end();
4934
(void) table->file->close(); // This deletes the table !
4937
plugin_unlock(0, table->s->db_plugin);
4938
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4939
new_table.s= table->s; // Keep old share
4943
table->file->change_table_ptr(table, table->s);
4944
table->use_all_columns();
4947
const char *new_proc_info=
4948
(!strcmp(save_proc_info,"Copying to tmp table") ?
4949
"Copying to tmp table on disk" : save_proc_info);
4950
session->set_proc_info(new_proc_info);
4955
table->file->print_error(write_err, MYF(0));
4956
(void) table->file->ha_rnd_end();
4957
(void) new_table.file->close();
4959
new_table.file->ha_delete_table(new_table.s->table_name.str);
4961
delete new_table.file;
4962
session->set_proc_info(save_proc_info);
4963
table->mem_root= new_table.mem_root;
4967
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4969
my_bitmap_map *old= bitmap->bitmap;
4970
bitmap->bitmap= s->all_set.bitmap;
1399
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4974
void Table::restore_column_map(my_bitmap_map *old)
1401
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
4976
read_set->bitmap= old;
1414
4979
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1416
4981
uint32_t min_length= UINT32_MAX;
1417
4982
uint32_t best= MAX_KEY;
1418
if (usable_keys->any())
4983
if (!usable_keys->is_clear_all())
1420
for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
4985
for (uint32_t nr=0; nr < s->keys ; nr++)
1422
if (usable_keys->test(nr))
4987
if (usable_keys->is_set(nr))
1424
4989
if (key_info[nr].key_length < min_length)