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, ".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, 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:
368
case DRIZZLE_TYPE_TIMESTAMP:
369
case DRIZZLE_TYPE_DATETIME:
370
case DRIZZLE_TYPE_DATE:
371
if(default_value.compare("NOW()")==0)
373
case DRIZZLE_TYPE_ENUM:
374
default_item= new Item_string(default_value.c_str(),
375
default_value.length(),
376
system_charset_info);
378
case DRIZZLE_TYPE_VARCHAR:
379
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
380
if(charset==&my_charset_bin)
382
default_item= new Item_string(default_bin_value.c_str(),
383
default_bin_value.length(),
388
default_item= new Item_string(default_value.c_str(),
389
default_value.length(),
390
system_charset_info);
393
case DRIZZLE_TYPE_VIRTUAL:
395
case DRIZZLE_TYPE_NEWDECIMAL:
396
default_item= new Item_decimal(default_value.c_str(),
397
default_value.length(),
398
system_charset_info);
405
int parse_table_proto(Session *session, drizzle::Table &table, TABLE_SHARE *share)
408
handler *handler_file= NULL;
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
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1108
session->count_cuted_fields= CHECK_FIELD_WARN;
1109
int res= default_value->save_in_field(f, 1);
1110
session->count_cuted_fields= old_count_cuted_fields;
1111
if (res != 0 && res != 3)
1113
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
1118
else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
1119
(f->flags & NOT_NULL_FLAG))
1122
f->store((int64_t) 1, true);
1127
/* hack to undo f->init() */
1129
f->orig_table= NULL;
1131
f->field_index= fieldnr;
1132
f->comment= comment;
1133
f->vcol_info= vcol_info;
1134
f->is_stored= field_is_stored;
1136
&& !(f->unireg_check==Field::NEXT_NUMBER)
1137
&& (f->flags & NOT_NULL_FLAG)
1138
&& (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
1139
f->flags|= NO_DEFAULT_VALUE_FLAG;
1141
if(f->unireg_check == Field::NEXT_NUMBER)
1142
share->found_next_number_field= &(share->field[fieldnr]);
1144
if(share->timestamp_field == f)
1145
share->timestamp_field_offset= fieldnr;
1147
if (use_hash) /* supposedly this never fails... but comments lie */
1148
(void) my_hash_insert(&share->name_hash,
1149
(unsigned char*)&(share->field[fieldnr]));
1153
share->stored_fields--;
1157
keyinfo= share->key_info;
1158
for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
1160
key_part= keyinfo->key_part;
1162
for(unsigned int partnr= 0;
1163
partnr < keyinfo->key_parts;
1164
partnr++, key_part++)
1166
/* Fix up key_part->offset by adding data_offset.
1167
We really should compute offset as well.
1168
But at least this way we are a little better. */
1169
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1174
We need to set the unused bits to 1. If the number of bits is a multiple
1175
of 8 there are no unused bits.
1179
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1181
share->null_bytes= (null_pos - (unsigned char*) record +
1182
(null_bit_pos + 7) / 8);
1184
share->last_null_bit_pos= null_bit_pos;
1186
free(field_offsets);
1187
free(field_pack_length);
1189
if(!(handler_file= get_new_handler(share, session->mem_root,
1194
if (share->key_parts)
1196
uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
1197
&share->keynames, 3) - 1);
1199
int64_t ha_option= handler_file->ha_table_flags();
1201
keyinfo= share->key_info;
1202
key_part= keyinfo->key_part;
1204
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1206
uint32_t usable_parts= 0;
1208
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1211
If the UNIQUE key doesn't have NULL columns and is not a part key
1212
declare this as a primary key.
1215
for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
1217
uint32_t fieldnr= key_part[i].fieldnr;
1219
share->field[fieldnr-1]->null_ptr ||
1220
share->field[fieldnr-1]->key_length() !=
1223
primary_key=MAX_KEY; // Can't be used
1229
for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1232
if (!key_part->fieldnr)
1234
// error= 4; // Wrong file
1235
abort(); // goto err;
1237
field= key_part->field= share->field[key_part->fieldnr-1];
1238
key_part->type= field->key_type();
1239
if (field->null_ptr)
1241
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1242
share->default_values);
1243
key_part->null_bit= field->null_bit;
1244
key_part->store_length+=HA_KEY_NULL_LENGTH;
1245
keyinfo->flags|=HA_NULL_PART_KEY;
1246
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1247
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1249
if (field->type() == DRIZZLE_TYPE_BLOB ||
1250
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1252
if (field->type() == DRIZZLE_TYPE_BLOB)
1253
key_part->key_part_flag|= HA_BLOB_PART;
1255
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1256
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1257
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1258
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1260
if (i == 0 && key != primary_key)
1261
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1262
(keyinfo->key_parts == 1)) ?
1263
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1265
field->key_start.set_bit(key);
1266
if (field->key_length() == key_part->length &&
1267
!(field->flags & BLOB_FLAG))
1269
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1271
share->keys_for_keyread.set_bit(key);
1272
field->part_of_key.set_bit(key);
1273
field->part_of_key_not_clustered.set_bit(key);
1275
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1276
field->part_of_sortkey.set_bit(key);
1278
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1280
usable_parts++; // For FILESORT
1281
field->flags|= PART_KEY_FLAG;
1282
if (key == primary_key)
1284
field->flags|= PRI_KEY_FLAG;
1286
If this field is part of the primary key and all keys contains
1287
the primary key, then we can use any key to find this column
1289
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1291
field->part_of_key= share->keys_in_use;
1292
if (field->part_of_sortkey.is_set(key))
1293
field->part_of_sortkey= share->keys_in_use;
1296
if (field->key_length() != key_part->length)
1298
key_part->key_part_flag|= HA_PART_KEY_SEG;
1301
keyinfo->usable_key_parts= usable_parts; // Filesort
1303
set_if_bigger(share->max_key_length,keyinfo->key_length+
1304
keyinfo->key_parts);
1305
share->total_key_length+= keyinfo->key_length;
1307
MERGE tables do not have unique indexes. But every key could be
1308
an unique index on the underlying MyISAM table. (Bug #10400)
1310
if ((keyinfo->flags & HA_NOSAME) ||
1311
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1312
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1314
if (primary_key < MAX_KEY &&
1315
(share->keys_in_use.is_set(primary_key)))
1317
share->primary_key= primary_key;
1319
If we are using an integer as the primary key then allow the user to
1320
refer to it as '_rowid'
1322
if (share->key_info[primary_key].key_parts == 1)
1324
Field *field= share->key_info[primary_key].key_part[0].field;
1325
if (field && field->result_type() == INT_RESULT)
1327
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1328
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1335
share->primary_key = MAX_KEY; // we do not have a primary key
1338
share->primary_key= MAX_KEY;
1340
if (share->found_next_number_field)
1342
Field *reg_field= *share->found_next_number_field;
1343
if ((int) (share->next_number_index= (uint32_t)
1344
find_ref_key(share->key_info, share->keys,
1345
share->default_values, reg_field,
1346
&share->next_number_key_offset,
1347
&share->next_number_keypart)) < 0)
1349
/* Wrong field definition */
1354
reg_field->flags |= AUTO_INCREMENT_FLAG;
1357
if (share->blob_fields)
1362
/* Store offsets to blob fields to find them fast */
1363
if (!(share->blob_field= save=
1364
(uint*) alloc_root(&share->mem_root,
1365
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1367
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1369
if ((*ptr)->flags & BLOB_FLAG)
1374
share->db_low_byte_first= handler_file->low_byte_first();
1375
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1377
my_bitmap_map *bitmaps;
1379
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1380
share->column_bitmap_size)))
1382
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1383
bitmap_set_all(&share->all_set);
1386
delete handler_file;
1390
share->error= error;
1391
share->open_errno= my_errno;
1393
hash_free(&share->name_hash);
1395
delete handler_file;
1396
open_table_error(share, error, share->open_errno, 0);
1401
Read table definition from a binary / text based .frm file
1405
session Thread handler
1406
share Fill this with table definition
1407
db_flags Bit mask of the following flags: OPEN_VIEW
1410
This function is called when the table definition is not cached in
1412
The data is returned in 'share', which is alloced by
1413
alloc_table_share().. The code assumes that share is initialized.
1417
1 Error (see open_table_error)
1418
2 Error (see open_table_error)
1419
3 Wrong data in .frm file
1420
4 Error (see open_table_error)
1421
5 Error (see open_table_error: charset unavailable)
1422
6 Unknown .frm version
1425
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
1429
string proto_path("");
1434
proto_path.reserve(FN_REFLEN);
1435
proto_path.append(share->normalized_path.str);
1437
proto_path.append(".dfe");
1439
drizzle::Table table;
1441
if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
1450
if(!table.IsInitialized())
1458
error= parse_table_proto(session, table, share);
1460
share->table_category= get_table_category(& share->db, & share->table_name);
1463
session->status_var.opened_shares++;
1466
if (error && !error_given)
1468
share->error= error;
1469
open_table_error(share, error, (share->open_errno= my_errno), 0);
1476
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1477
This routine is used for error handling purposes.
1481
table Table object for which virtual columns are set-up
1486
static void clear_field_flag(Table *table)
1490
for (ptr= table->field; *ptr; ptr++)
1491
(*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1495
The function uses the feature in fix_fields where the flag
1496
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1497
This field must always be reset before returning from the function
1498
since it is used for other purposes as well.
1501
fix_fields_vcol_func()
1502
session The thread object
1503
func_item The item tree reference of the virtual columnfunction
1504
table The table object
1505
field_name The name of the processed field
1508
true An error occurred, something was wrong with the
1510
false Ok, a partition field array was created
1513
bool fix_fields_vcol_func(Session *session,
1516
const char *field_name)
1518
uint32_t dir_length, home_dir_length;
1521
TableList *save_table_list, *save_first_table, *save_last_table;
1523
Name_resolution_context *context;
1524
const char *save_where;
1526
char db_name_string[FN_REFLEN];
1527
bool save_use_only_table_context;
1528
Field **ptr, *field;
1529
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1533
Set-up the TABLE_LIST object to be a list with a single table
1534
Set the object to zero to create NULL pointers and set alias
1535
and real name to table name and get database name from file name.
1538
bzero((void*)&tables, sizeof(TableList));
1539
tables.alias= tables.table_name= (char*) table->s->table_name.str;
1540
tables.table= table;
1541
tables.next_local= NULL;
1542
tables.next_name_resolution_table= NULL;
1543
memcpy(db_name_string,
1544
table->s->normalized_path.str,
1545
table->s->normalized_path.length);
1546
db_name_string[table->s->normalized_path.length]= '\0';
1547
dir_length= dirname_length(db_name_string);
1548
db_name_string[dir_length - 1]= 0;
1549
home_dir_length= dirname_length(db_name_string);
1550
db_name= &db_name_string[home_dir_length];
1553
session->mark_used_columns= MARK_COLUMNS_NONE;
1555
context= session->lex->current_context();
1556
table->map= 1; //To ensure correct calculation of const item
1557
table->get_fields_in_item_tree= true;
1558
save_table_list= context->table_list;
1559
save_first_table= context->first_name_resolution_table;
1560
save_last_table= context->last_name_resolution_table;
1561
context->table_list= &tables;
1562
context->first_name_resolution_table= &tables;
1563
context->last_name_resolution_table= NULL;
1564
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1565
save_where= session->where;
1566
session->where= "virtual column function";
1568
/* Save the context before fixing the fields*/
1569
save_use_only_table_context= session->lex->use_only_table_context;
1570
session->lex->use_only_table_context= true;
1571
/* Fix fields referenced to by the virtual column function */
1572
error= func_expr->fix_fields(session, (Item**)0);
1573
/* Restore the original context*/
1574
session->lex->use_only_table_context= save_use_only_table_context;
1575
context->table_list= save_table_list;
1576
context->first_name_resolution_table= save_first_table;
1577
context->last_name_resolution_table= save_last_table;
1579
if (unlikely(error))
1581
clear_field_flag(table);
1584
session->where= save_where;
1586
Walk through the Item tree checking if all items are valid
1587
to be part of the virtual column
1589
error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1592
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1593
clear_field_flag(table);
1596
if (unlikely(func_expr->const_item()))
1598
my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1599
clear_field_flag(table);
1602
/* Ensure that this virtual column is not based on another virtual field. */
1604
while ((field= *(ptr++)))
1606
if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1609
my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1610
clear_field_flag(table);
1615
Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1616
when calling fix_fields.
1618
clear_field_flag(table);
1622
table->get_fields_in_item_tree= false;
1623
session->mark_used_columns= save_mark_used_columns;
1624
table->map= 0; //Restore old value
1629
Unpack the definition of a virtual column
1632
unpack_vcol_info_from_frm()
1633
session Thread handler
1634
table Table with the checked field
1635
field Pointer to Field object
1636
open_mode Open table mode needed to determine
1637
which errors need to be generated in a failure
1638
error_reported updated flag for the caller that no other error
1639
messages are to be generated.
1645
bool unpack_vcol_info_from_frm(Session *session,
1648
LEX_STRING *vcol_expr,
1649
open_table_mode open_mode,
1650
bool *error_reported)
1655
Step 1: Construct a statement for the parser.
1656
The parsed string needs to take the following format:
1657
"PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1659
char *vcol_expr_str;
1662
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1664
parse_vcol_keyword.length + 3)))
1668
memcpy(vcol_expr_str,
1669
(char*) parse_vcol_keyword.str,
1670
parse_vcol_keyword.length);
1671
str_len= parse_vcol_keyword.length;
1672
memcpy(vcol_expr_str + str_len, "(", 1);
1674
memcpy(vcol_expr_str + str_len,
1675
(char*) vcol_expr->str,
1677
str_len+= vcol_expr->length;
1678
memcpy(vcol_expr_str + str_len, ")", 1);
1680
memcpy(vcol_expr_str + str_len, "\0", 1);
1682
Lex_input_stream lip(session, vcol_expr_str, str_len);
1685
Step 2: Setup session for parsing.
1686
1) make Item objects be created in the memory allocated for the Table
1687
object (not TABLE_SHARE)
1688
2) ensure that created Item's are not put on to session->free_list
1689
(which is associated with the parsed statement and hence cleared after
1691
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1692
to be parsed as a SQL command.
1694
MEM_ROOT **root_ptr, *old_root;
1695
Item *backup_free_list= session->free_list;
1696
root_ptr= current_mem_root_ptr();
1697
old_root= *root_ptr;
1698
*root_ptr= &table->mem_root;
1699
session->free_list= NULL;
1700
session->lex->parse_vcol_expr= true;
1703
Step 3: Use the parser to build an Item object from.
1705
if (parse_sql(session, &lip))
1709
/* From now on use vcol_info generated by the parser. */
1710
field->vcol_info= session->lex->vcol_info;
1712
/* Validate the Item tree. */
1713
if (fix_fields_vcol_func(session,
1714
field->vcol_info->expr_item,
1718
if (open_mode == OTM_CREATE)
1721
During CREATE/ALTER TABLE it is ok to receive errors here.
1722
It is not ok if it happens during the opening of an frm
1723
file as part of a normal query.
1725
*error_reported= true;
1727
field->vcol_info= NULL;
1730
field->vcol_info->item_free_list= session->free_list;
1731
session->free_list= backup_free_list;
1732
*root_ptr= old_root;
1737
session->lex->parse_vcol_expr= false;
1738
session->free_items();
1739
*root_ptr= old_root;
1740
session->free_list= backup_free_list;
1746
Open a table based on a TABLE_SHARE
1749
open_table_from_share()
1750
session Thread handler
1751
share Table definition
1752
alias Alias for table
1753
db_stat open flags (for example HA_OPEN_KEYFILE|
1754
HA_OPEN_RNDFILE..) can be 0 (example in
1756
prgflag READ_ALL etc..
1757
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1758
outparam result table
1759
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1760
if OTM_CREATE some errors are ignore
1761
if OTM_ALTER HA_OPEN is not called
1765
1 Error (see open_table_error)
1766
2 Error (see open_table_error)
1767
3 Wrong data in .frm file
1768
4 Error (see open_table_error)
1769
5 Error (see open_table_error: charset unavailable)
1770
7 Table definition has changed in engine
1773
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1774
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1775
Table *outparam, open_table_mode open_mode)
1778
uint32_t records, i, bitmap_size;
1779
bool error_reported= false;
1780
unsigned char *record, *bitmaps;
1781
Field **field_ptr, **vfield_ptr;
1783
/* Parsing of partitioning information from .frm needs session->lex set up. */
1784
assert(session->lex->is_lex_started);
1787
memset(outparam, 0, sizeof(*outparam));
1788
outparam->in_use= session;
1790
outparam->db_stat= db_stat;
1791
outparam->write_row_record= NULL;
1793
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1795
if (!(outparam->alias= strdup(alias)))
1797
outparam->quick_keys.init();
1798
outparam->covering_keys.init();
1799
outparam->keys_in_use_for_query.init();
1801
/* Allocate handler */
1803
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1805
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1815
outparam->reginfo.lock_type= TL_UNLOCK;
1816
outparam->current_lock= F_UNLCK;
1818
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1820
if (prgflag & (READ_ALL+EXTRA_RECORD))
1823
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1824
share->rec_buff_length * records)))
1825
goto err; /* purecov: inspected */
1829
/* We are probably in hard repair, and the buffers should not be used */
1830
outparam->record[0]= outparam->record[1]= share->default_values;
1834
outparam->record[0]= record;
1836
outparam->record[1]= record+ share->rec_buff_length;
1838
outparam->record[1]= outparam->record[0]; // Safety
1843
We need this because when we read var-length rows, we are not updating
1844
bytes after end of varchar
1848
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1849
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1851
memcpy(outparam->record[1], share->default_values,
1852
share->rec_buff_length);
1856
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1857
(uint32_t) ((share->fields+1)*
1859
goto err; /* purecov: inspected */
1861
outparam->field= field_ptr;
1863
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1865
outparam->null_flags= (unsigned char*) record+1;
1867
/* Setup copy of fields from share, but use the right alias and record */
1868
for (i=0 ; i < share->fields; i++, field_ptr++)
1870
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1873
(*field_ptr)= 0; // End marker
1875
if (share->found_next_number_field)
1876
outparam->found_next_number_field=
1877
outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1878
if (share->timestamp_field)
1879
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1882
/* Fix key->name and key_part->field */
1883
if (share->key_parts)
1885
KEY *key_info, *key_info_end;
1886
KEY_PART_INFO *key_part;
1888
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1889
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1891
outparam->key_info= key_info;
1892
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1894
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1895
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1898
for (key_info_end= key_info + share->keys ;
1899
key_info < key_info_end ;
1902
KEY_PART_INFO *key_part_end;
1904
key_info->table= outparam;
1905
key_info->key_part= key_part;
1907
for (key_part_end= key_part+ key_info->key_parts ;
1908
key_part < key_part_end ;
1911
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1913
if (field->key_length() != key_part->length &&
1914
!(field->flags & BLOB_FLAG))
1917
We are using only a prefix of the column as a key:
1918
Create a new field for the key part that matches the index
1920
field= key_part->field=field->new_field(&outparam->mem_root,
1922
field->field_length= key_part->length;
1929
Process virtual columns, if any.
1931
if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
1932
(uint32_t) ((share->vfields+1)*
1936
outparam->vfield= vfield_ptr;
1938
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
1940
if ((*field_ptr)->vcol_info)
1942
if (unpack_vcol_info_from_frm(session,
1945
&(*field_ptr)->vcol_info->expr_str,
1949
error= 4; // in case no error is reported
1952
*(vfield_ptr++)= *field_ptr;
1955
*vfield_ptr= NULL; // End marker
1956
/* Check virtual columns against table's storage engine. */
1957
if ((share->vfields && outparam->file) &&
1958
(not outparam->file->check_if_supported_virtual_columns()))
1960
my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
1962
"Specified storage engine");
1963
error_reported= true;
1967
/* Allocate bitmaps */
1969
bitmap_size= share->column_bitmap_size;
1970
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1972
bitmap_init(&outparam->def_read_set,
1973
(my_bitmap_map*) bitmaps, share->fields, false);
1974
bitmap_init(&outparam->def_write_set,
1975
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1976
bitmap_init(&outparam->tmp_set,
1977
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1978
outparam->default_column_bitmaps();
1980
/* The table struct is now initialized; Open the table */
1982
if (db_stat && open_mode != OTM_ALTER)
1985
if ((ha_err= (outparam->file->
1986
ha_open(outparam, share->normalized_path.str,
1987
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1988
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1989
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1990
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1991
HA_OPEN_ABORT_IF_LOCKED :
1992
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1994
/* Set a flag if the table is crashed and it can be auto. repaired */
1995
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1996
outparam->file->auto_repair() &&
1997
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
2001
case HA_ERR_NO_SUCH_TABLE:
2003
The table did not exists in storage engine, use same error message
2004
as if the .frm file didn't exist
2011
Too many files opened, use same error message as if the .frm
2018
outparam->file->print_error(ha_err, MYF(0));
2019
error_reported= true;
2020
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
2024
goto err; /* purecov: inspected */
2028
#if defined(HAVE_purify)
2029
memset(bitmaps, 0, bitmap_size*3);
2032
outparam->no_replicate= outparam->file;
2033
session->status_var.opened_tables++;
2038
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
2039
open_table_error(share, error, my_errno, 0);
2040
delete outparam->file;
2041
outparam->file= 0; // For easier error checking
2042
outparam->db_stat=0;
2043
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
2044
free((char*) outparam->alias);
2048
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
2049
uint32_t Table::tmpkeyval()
2051
return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
2055
Free information allocated by openfrm
2059
table Table object to free
2060
free_share Is 1 if we also want to free table_share
2063
int Table::closefrm(bool free_share)
83
error= cursor->close();
2068
error= file->close();
2069
free((char*) alias);
88
2073
for (Field **ptr=field ; *ptr ; ptr++)
2078
file= 0; /* For easier errorchecking */
2081
if (s->tmp_table == NO_TMP_TABLE)
2082
release_table_share(s, RELEASE_NORMAL);
2084
free_table_share(s);
2086
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
2092
/* Deallocate temporary blob storage */
200
void free_blobs(Table *table)
2094
void free_blobs(register Table *table)
202
2096
uint32_t *ptr, *end;
203
2097
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));
2100
((Field_blob*) table->field[*ptr])->free();
2104
/* Find where a form starts */
2105
/* if formname is NULL then only formnames is read */
2107
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
2109
uint32_t a_length,names,length;
2110
unsigned char *pos,*buf;
2113
names=uint2korr(head+8);
2114
a_length=(names+2)*sizeof(char *); /* Room for two extra */
2119
save_names->type_names=0; /* Clear if error */
2123
length=uint2korr(head+4);
2124
lseek(file,64,SEEK_SET);
2125
if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
2126
my_read(file, buf+a_length, (size_t) (length+names*4),
2128
{ /* purecov: inspected */
2131
return(0L); /* purecov: inspected */
2133
pos= buf+a_length+length;
2134
ret_value=uint4korr(pos);
2139
free((unsigned char*) buf);
2142
memset(save_names, 0, sizeof(save_names));
2146
str=(char *) (buf+a_length);
2147
fix_type_pointers((const char ***) &buf,save_names,1,&str);
2154
Read string from a file with malloc
2157
We add an \0 at end of the read string to make reading of C strings easier
2160
int read_string(File file, unsigned char**to, size_t length)
2165
if (!(*to= (unsigned char*) malloc(length+1)) ||
2166
my_read(file, *to, length,MYF(MY_NABP)))
2171
return(1); /* purecov: inspected */
2173
*((char*) *to+length)= '\0';
2178
/* Add a new form to a form file */
2180
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
2181
const char *newname)
2183
uint32_t i,bufflength,maxlength,n_length,length,names;
2184
off_t endpos,newpos;
2185
unsigned char buff[IO_SIZE];
2188
length=(uint32_t) strlen(newname)+1;
2189
n_length=uint2korr(fileinfo+4);
2190
maxlength=uint2korr(fileinfo+6);
2191
names=uint2korr(fileinfo+8);
2192
newpos=uint4korr(fileinfo+10);
2194
if (64+length+n_length+(names+1)*4 > maxlength)
2197
int4store(fileinfo+10,newpos);
2198
endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
2199
bufflength= (uint32_t) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */
2201
while (endpos > maxlength)
2203
lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
2204
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
2206
lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
2207
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
2209
endpos-=bufflength; bufflength=IO_SIZE;
2211
memset(buff, 0, IO_SIZE); /* Null new block */
2212
lseek(file,(ulong) maxlength,SEEK_SET);
2213
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
2215
maxlength+=IO_SIZE; /* Fix old ref */
2216
int2store(fileinfo+6,maxlength);
2217
for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
2220
endpos=uint4korr(pos)+IO_SIZE;
2221
int4store(pos,endpos);
2228
sprintf((char*)buff,"/%s/",newname);
2231
sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
2232
lseek(file, 63 + n_length,SEEK_SET);
2233
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
2234
(names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
2235
names*4, MYF(MY_NABP+MY_WME))) ||
2236
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
2237
return(0L); /* purecov: inspected */
2239
int2store(fileinfo+8,names+1);
2240
int2store(fileinfo+4,n_length+length);
2241
assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
2243
} /* make_new_entry */
2246
/* error message when opening a form file */
2248
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
2251
char buff[FN_REFLEN];
2252
myf errortype= ME_ERROR+ME_WAITTANG;
2257
if (db_errno == ENOENT)
2258
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
2261
sprintf(buff,"%s",share->normalized_path.str);
2262
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
2263
errortype, buff, db_errno);
2269
const char *datext= "";
2271
if (share->db_type() != NULL)
2273
if ((file= get_new_handler(share, current_session->mem_root,
2276
if (!(datext= *file->bas_ext()))
2280
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
2281
ER_FILE_USED : ER_CANT_OPEN_FILE;
2282
sprintf(buff,"%s%s", share->normalized_path.str,datext);
2283
my_error(err_no,errortype, buff, db_errno);
2289
const char *csname= get_charset_name((uint32_t) errarg);
2291
if (!csname || csname[0] =='?')
2293
snprintf(tmp, sizeof(tmp), "#%d", errarg);
2296
my_printf_error(ER_UNKNOWN_COLLATION,
2297
_("Unknown collation '%s' in table '%-.64s' definition"),
2298
MYF(0), csname, share->table_name.str);
2302
sprintf(buff,"%s",share->normalized_path.str);
2303
my_printf_error(ER_NOT_FORM_FILE,
2304
_("Table '%-.64s' was created with a different version "
2305
"of Drizzle and cannot be read"),
2310
default: /* Better wrong error than none */
2312
sprintf(buff,"%s",share->normalized_path.str);
2313
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
2317
} /* open_table_error */
2321
** fix a str_type to a array type
2322
** typeparts separated with some char. differents types are separated
2327
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
2330
char *type_name, *ptr;
2336
point_to_type->name=0;
2337
point_to_type->type_names= *array;
2339
if ((chr= *ptr)) /* Test if empty type */
2341
while ((type_name=strchr(ptr+1,chr)) != NULL)
2343
*((*array)++) = ptr+1;
2344
*type_name= '\0'; /* End string */
2347
ptr+=2; /* Skip end mark and last 0 */
2351
point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
2353
*((*array)++)= NULL; /* End of type */
2355
*names=ptr; /* Update end */
2357
} /* fix_type_pointers */
2360
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
2362
TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
217
result->count= strings.elements;
2365
result->count=strings.elements;
219
2367
uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
221
if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
2368
if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
224
2370
result->type_lengths= (uint*) (result->type_names + result->count + 1);
226
List<String>::iterator it(strings.begin());
2371
List_iterator<String> it(strings);
228
for (uint32_t i= 0; (tmp= it++); i++)
2373
for (uint32_t i=0; (tmp=it++) ; i++)
230
2375
result->type_names[i]= tmp->ptr();
231
2376
result->type_lengths[i]= tmp->length();
234
result->type_names[result->count]= 0; // End marker
2378
result->type_names[result->count]= 0; // End marker
235
2379
result->type_lengths[result->count]= 0;
240
2383
/* Check that the integer is in the internal */
242
int set_zone(int nr, int min_zone, int max_zone)
2385
int set_zone(register int nr, int min_zone, int max_zone)
244
2387
if (nr<=min_zone)
245
2388
return (min_zone);
1376
4424
session->mem_root= mem_root_save;
4425
table->free_tmp_table(session); /* purecov: inspected */
4426
if (temp_pool_slot != MY_BIT_NONE)
4427
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4428
return(NULL); /* purecov: inspected */
1382
4431
/****************************************************************************/
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;
4434
Create a reduced Table object with properly set up Field list from a
4435
list of field definitions.
4437
The created table doesn't have a table handler associated with
4438
it, has no keys, no group/distinct, no copy_funcs array.
4439
The sole purpose of this Table object is to use the power of Field
4440
class to read/write data to/from table->record[0]. Then one can store
4441
the record in any container (RB tree, hash, etc).
4442
The table is created in Session mem_root, so are the table's fields.
4443
Consequently, if you don't BLOB fields, you don't need to free it.
4445
@param session connection handle
4446
@param field_list list of column definitions
4449
0 if out of memory, Table object in case of success
4452
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4454
uint32_t field_count= field_list.elements;
4455
uint32_t blob_count= 0;
4457
Create_field *cdef; /* column definition */
4458
uint32_t record_length= 0;
4459
uint32_t null_count= 0; /* number of columns which may be null */
4460
uint32_t null_pack_length; /* NULL representation array length */
4461
uint32_t *blob_field;
4462
unsigned char *bitmaps;
4466
if (!multi_alloc_root(session->mem_root,
4467
&table, sizeof(*table),
4468
&share, sizeof(*share),
4469
&field, (field_count + 1) * sizeof(Field*),
4470
&blob_field, (field_count+1) *sizeof(uint32_t),
4471
&bitmaps, bitmap_buffer_size(field_count)*2,
4475
memset(table, 0, sizeof(*table));
4476
memset(share, 0, sizeof(*share));
4477
table->field= field;
4479
share->blob_field= blob_field;
4480
share->fields= field_count;
4481
share->blob_ptr_size= portable_sizeof_char_ptr;
4482
table->setup_tmp_table_column_bitmaps(bitmaps);
4484
/* Create all fields and calculate the total length of record */
4485
List_iterator_fast<Create_field> it(field_list);
4486
while ((cdef= it++))
4488
*field= make_field(share, NULL, 0, cdef->length,
4489
(unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4490
f_maybe_null(cdef->pack_flag) ? 1 : 0,
4491
cdef->pack_flag, cdef->sql_type, cdef->charset,
4493
cdef->interval, cdef->field_name);
4496
(*field)->init(table);
4497
record_length+= (*field)->pack_length();
4498
if (! ((*field)->flags & NOT_NULL_FLAG))
4501
if ((*field)->flags & BLOB_FLAG)
4502
share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4506
*field= NULL; /* mark the end of the list */
4507
share->blob_field[blob_count]= 0; /* mark the end of the list */
4508
share->blob_fields= blob_count;
4510
null_pack_length= (null_count + 7)/8;
4511
share->reclength= record_length + null_pack_length;
4512
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4513
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4514
if (!table->record[0])
4517
if (null_pack_length)
4519
table->null_flags= (unsigned char*) table->record[0];
4520
share->null_fields= null_count;
4521
share->null_bytes= null_pack_length;
4524
table->in_use= session; /* field->reset() may access table->in_use */
4526
/* Set up field pointers */
4527
unsigned char *null_pos= table->record[0];
4528
unsigned char *field_pos= null_pos + share->null_bytes;
4529
uint32_t null_bit= 1;
4531
for (field= table->field; *field; ++field)
4533
Field *cur_field= *field;
4534
if ((cur_field->flags & NOT_NULL_FLAG))
4535
cur_field->move_field(field_pos);
4538
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
4540
if (null_bit == (1 << 8))
4548
field_pos+= cur_field->pack_length();
4553
for (field= table->field; *field; ++field)
4554
delete *field; /* just invokes field destructor */
4559
bool Table::open_tmp_table()
4562
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4563
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4565
file->print_error(error,MYF(0)); /* purecov: inspected */
4569
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
4575
Create MyISAM temporary table
4578
create_myisam_tmp_table()
4579
keyinfo Description of the index (there is always one index)
4580
start_recinfo MyISAM's column descriptions
4581
recinfo INOUT End of MyISAM's column descriptions
4585
Create a MyISAM temporary table according to passed description. The is
4586
assumed to have one unique index or constraint.
4588
The passed array or MI_COLUMNDEF structures must have this form:
4590
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4591
when there are many nullable columns)
4593
3. One free MI_COLUMNDEF element (*recinfo points here)
4595
This function may use the free element to create hash column for unique
4603
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4604
MI_COLUMNDEF *start_recinfo,
4605
MI_COLUMNDEF **recinfo,
4610
MI_UNIQUEDEF uniquedef;
4611
TABLE_SHARE *share= s;
4614
{ // Get keys for ni_create
4615
bool using_unique_constraint=0;
4616
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4617
sizeof(*seg) * keyinfo->key_parts);
4621
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4622
if (keyinfo->key_length >= file->max_key_length() ||
4623
keyinfo->key_parts > file->max_key_parts() ||
4626
/* Can't create a key; Make a unique constraint instead of a key */
4629
using_unique_constraint=1;
4630
memset(&uniquedef, 0, sizeof(uniquedef));
4631
uniquedef.keysegs=keyinfo->key_parts;
4633
uniquedef.null_are_equal=1;
4635
/* Create extra column for hash value */
4636
memset(*recinfo, 0, sizeof(**recinfo));
4637
(*recinfo)->type= FIELD_CHECK;
4638
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4640
share->reclength+=MI_UNIQUE_HASH_LENGTH;
4644
/* Create an unique key */
4645
memset(&keydef, 0, sizeof(keydef));
4646
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4647
keydef.keysegs= keyinfo->key_parts;
4650
for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4652
Field *key_field=keyinfo->key_part[i].field;
4654
seg->language= key_field->charset()->number;
4655
seg->length= keyinfo->key_part[i].length;
4656
seg->start= keyinfo->key_part[i].offset;
4657
if (key_field->flags & BLOB_FLAG)
4660
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4661
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4662
seg->bit_start= (uint8_t)(key_field->pack_length()
4663
- share->blob_ptr_size);
4664
seg->flag= HA_BLOB_PART;
4665
seg->length=0; // Whole blob in unique constraint
4669
seg->type= keyinfo->key_part[i].type;
4671
if (!(key_field->flags & NOT_NULL_FLAG))
4673
seg->null_bit= key_field->null_bit;
4674
seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4676
We are using a GROUP BY on something that contains NULL
4677
In this case we have to tell MyISAM that two NULL should
4678
on INSERT be regarded at the same value
4680
if (!using_unique_constraint)
4681
keydef.flag|= HA_NULL_ARE_EQUAL;
4685
MI_CREATE_INFO create_info;
4686
memset(&create_info, 0, sizeof(create_info));
4688
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4690
create_info.data_file_length= ~(uint64_t) 0;
4692
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4693
(uint32_t) (*recinfo-start_recinfo),
4695
share->uniques, &uniquedef,
4697
HA_CREATE_TMP_TABLE)))
4699
file->print_error(error,MYF(0)); /* purecov: inspected */
4703
status_var_increment(in_use->status_var.created_tmp_disk_tables);
4704
share->db_record_offset= 1;
4711
void Table::free_tmp_table(Session *session)
4713
MEM_ROOT own_root= mem_root;
4714
const char *save_proc_info;
4716
save_proc_info=session->get_proc_info();
4717
session->set_proc_info("removing tmp table");
4719
// Release latches since this can take a long time
4720
ha_release_temporary_latches(session);
4725
file->ha_drop_table(s->table_name.str);
4727
file->ha_delete_table(s->table_name.str);
4732
for (Field **ptr= field ; *ptr ; ptr++)
4734
free_io_cache(this);
4736
if (temp_pool_slot != MY_BIT_NONE)
4737
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4739
plugin_unlock(0, s->db_plugin);
4741
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4742
session->set_proc_info(save_proc_info);
4748
If a HEAP table gets full, create a MyISAM table and copy all rows
4752
bool create_myisam_from_heap(Session *session, Table *table,
4753
MI_COLUMNDEF *start_recinfo,
4754
MI_COLUMNDEF **recinfo,
4755
int error, bool ignore_last_dupp_key_error)
4759
const char *save_proc_info;
4762
if (table->s->db_type() != heap_hton ||
4763
error != HA_ERR_RECORD_FILE_FULL)
4765
table->file->print_error(error,MYF(0));
4769
// Release latches since this can take a long time
4770
ha_release_temporary_latches(session);
4774
new_table.s= &share;
4775
new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4776
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4777
new_table.s->db_type())))
4778
return(1); // End of memory
4780
save_proc_info=session->get_proc_info();
4781
session->set_proc_info("converting HEAP to MyISAM");
4783
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4784
recinfo, session->lex->select_lex.options |
4787
if (new_table.open_tmp_table())
4789
if (table->file->indexes_are_disabled())
4790
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4791
table->file->ha_index_or_rnd_end();
4792
table->file->ha_rnd_init(1);
4795
new_table.file->extra(HA_EXTRA_NO_ROWS);
4796
new_table.no_rows=1;
4799
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4800
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4803
copy all old rows from heap table to MyISAM table
4804
This is the only code that uses record[1] to read/write but this
4805
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4807
while (!table->file->rnd_next(new_table.record[1]))
4809
write_err= new_table.file->ha_write_row(new_table.record[1]);
4813
/* copy row that filled HEAP table */
4814
if ((write_err=new_table.file->ha_write_row(table->record[0])))
4816
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4817
!ignore_last_dupp_key_error)
4821
/* remove heap table and change to use myisam table */
4822
(void) table->file->ha_rnd_end();
4823
(void) table->file->close(); // This deletes the table !
4826
plugin_unlock(0, table->s->db_plugin);
4827
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4828
new_table.s= table->s; // Keep old share
4832
table->file->change_table_ptr(table, table->s);
4833
table->use_all_columns();
4836
const char *new_proc_info=
4837
(!strcmp(save_proc_info,"Copying to tmp table") ?
4838
"Copying to tmp table on disk" : save_proc_info);
4839
session->set_proc_info(new_proc_info);
4844
table->file->print_error(write_err, MYF(0));
4845
(void) table->file->ha_rnd_end();
4846
(void) new_table.file->close();
4848
new_table.file->ha_delete_table(new_table.s->table_name.str);
4850
delete new_table.file;
4851
session->set_proc_info(save_proc_info);
4852
table->mem_root= new_table.mem_root;
4856
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4858
my_bitmap_map *old= bitmap->bitmap;
4859
bitmap->bitmap= s->all_set.bitmap;
1399
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4863
void Table::restore_column_map(my_bitmap_map *old)
1401
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
4865
read_set->bitmap= old;
1414
4868
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1416
4870
uint32_t min_length= UINT32_MAX;
1417
4871
uint32_t best= MAX_KEY;
1418
if (usable_keys->any())
4872
if (!usable_keys->is_clear_all())
1420
for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
4874
for (uint32_t nr=0; nr < s->keys ; nr++)
1422
if (usable_keys->test(nr))
4876
if (usable_keys->is_set(nr))
1424
4878
if (key_info[nr].key_length < min_length)