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 */
28
#include <drizzled/error.h>
29
#include <drizzled/gettext.h>
31
#include "drizzled/plugin/transactional_storage_engine.h"
32
#include "drizzled/plugin/authorization.h"
33
#include <drizzled/nested_join.h>
34
#include <drizzled/sql_parse.h>
35
#include <drizzled/item/sum.h>
36
#include <drizzled/table_list.h>
37
#include <drizzled/session.h>
38
#include <drizzled/sql_base.h>
39
#include <drizzled/sql_select.h>
40
#include <drizzled/field/blob.h>
41
#include <drizzled/field/varstring.h>
42
#include <drizzled/field/double.h>
43
#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"
50
#include <drizzled/item/string.h>
51
#include <drizzled/item/int.h>
52
#include <drizzled/item/decimal.h>
53
#include <drizzled/item/float.h>
54
#include <drizzled/item/null.h>
55
#include <drizzled/temporal.h>
57
#include "drizzled/table/instance.h"
59
#include "drizzled/table_proto.h"
66
extern pid_t current_pid;
67
extern plugin::StorageEngine *heap_engine;
68
extern plugin::StorageEngine *myisam_engine;
70
/* Functions defined in this cursor */
72
void open_table_error(TableShare *share, int error, int db_errno,
19
#include <drizzled/server_includes.h>
20
#include <drizzled/drizzled_error_messages.h>
22
#include "tmp_table.h"
23
#include "sj_tmp_table.h"
25
/* INFORMATION_SCHEMA name */
26
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
28
/* Functions defined in this file */
30
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
73
31
myf errortype, int errarg);
32
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
uchar *head, File file);
34
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
35
uint types, char **names);
36
static uint find_field(Field **fields, uchar *record, uint start, uint length);
75
38
/*************************************************************************/
77
// @note this should all be the destructor
78
int Table::delete_table(bool free_share)
83
error= cursor->close();
87
for (Field **ptr=field ; *ptr ; ptr++)
40
/* Get column name from column hash */
42
static uchar *get_field_name(Field **buff, size_t *length,
43
bool not_used __attribute__((unused)))
45
*length= (uint) strlen((*buff)->field_name);
46
return (uchar*) (*buff)->field_name;
51
Returns pointer to '.frm' extension of the file name.
58
Checks file name part starting with the rightmost '.' character,
59
and returns it if it is equal to '.frm'.
62
It is a good idea to get rid of this function modifying the code
63
to garantee that the functions presently calling fn_rext() always
64
get arguments in the same format: either with '.frm' or without '.frm'.
67
Pointer to the '.frm' extension. If there is no extension,
68
or extension is not '.frm', pointer at the end of file name.
71
char *fn_rext(char *name)
73
char *res= strrchr(name, '.');
74
if (res && !strcmp(res, reg_ext))
76
return name + strlen(name);
79
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
84
if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
85
(my_strcasecmp(system_charset_info,
86
INFORMATION_SCHEMA_NAME.str,
89
return TABLE_CATEGORY_INFORMATION;
92
return TABLE_CATEGORY_USER;
97
Allocate a setup TABLE_SHARE structure
101
TableList Take database and table name from there
102
key Table cache key (db \0 table_name \0...)
103
key_length Length of key
106
0 Error (out of memory)
110
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
115
char *key_buff, *path_buff;
116
char path[FN_REFLEN];
119
path_length= build_table_filename(path, sizeof(path) - 1,
121
table_list->table_name, "", 0);
122
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
123
if (multi_alloc_root(&mem_root,
124
&share, sizeof(*share),
125
&key_buff, key_length,
126
&path_buff, path_length + 1,
129
memset(share, 0, sizeof(*share));
131
share->set_table_cache_key(key_buff, key, key_length);
133
share->path.str= path_buff;
134
share->path.length= path_length;
135
stpcpy(share->path.str, path);
136
share->normalized_path.str= share->path.str;
137
share->normalized_path.length= path_length;
139
share->version= refresh_version;
142
This constant is used to mark that no table map version has been
143
assigned. No arithmetic is done on the value: it will be
144
overwritten with a value taken from DRIZZLE_BIN_LOG.
146
share->table_map_version= UINT64_MAX;
149
Since alloc_table_share() can be called without any locking (for
150
example, ha_create_table... functions), we do not assign a table
151
map id here. Instead we assign a value that is not used
152
elsewhere, and then assign a table map id inside open_table()
153
under the protection of the LOCK_open mutex.
155
share->table_map_id= UINT32_MAX;
156
share->cached_row_logging_check= -1;
158
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
159
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
160
pthread_cond_init(&share->cond, NULL);
167
Initialize share for temporary tables
170
init_tmp_table_share()
173
key Table_cache_key, as generated from create_table_def_key.
174
must start with db name.
175
key_length Length of key
176
table_name Table name
177
path Path to file (possible in lower case) without .frm
180
This is different from alloc_table_share() because temporary tables
181
don't have to be shared between threads or put into the table def
182
cache, so we can do some things notable simpler and faster
184
If table is not put in thd->temporary_tables (happens only when
185
one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
use key_length= 0 as neither table_cache_key or key_length will be used).
189
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
190
uint key_length, const char *table_name,
194
memset(share, 0, sizeof(*share));
195
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
196
share->table_category= TABLE_CATEGORY_TEMPORARY;
197
share->tmp_table= INTERNAL_TMP_TABLE;
198
share->db.str= (char*) key;
199
share->db.length= strlen(key);
200
share->table_cache_key.str= (char*) key;
201
share->table_cache_key.length= key_length;
202
share->table_name.str= (char*) table_name;
203
share->table_name.length= strlen(table_name);
204
share->path.str= (char*) path;
205
share->normalized_path.str= (char*) path;
206
share->path.length= share->normalized_path.length= strlen(path);
207
share->frm_version= FRM_VER_TRUE_VARCHAR;
209
Temporary tables are not replicated, but we set up these fields
210
anyway to be able to catch errors.
212
share->table_map_version= ~(uint64_t)0;
213
share->cached_row_logging_check= -1;
216
table_map_id is also used for MERGE tables to suppress repeated
217
compatibility checks.
219
share->table_map_id= (ulong) thd->query_id;
226
Free table share and memory used by it
233
share->mutex must be locked when we come here if it's not a temp table
236
void free_table_share(TABLE_SHARE *share)
239
assert(share->ref_count == 0);
242
If someone is waiting for this to be deleted, inform it about this.
243
Don't do a delete until we know that no one is refering to this anymore.
245
if (share->tmp_table == NO_TMP_TABLE)
247
/* share->mutex is locked in release_table_share() */
248
while (share->waiting_on_cond)
250
pthread_cond_broadcast(&share->cond);
251
pthread_cond_wait(&share->cond, &share->mutex);
253
/* No thread refers to this anymore */
254
pthread_mutex_unlock(&share->mutex);
255
pthread_mutex_destroy(&share->mutex);
256
pthread_cond_destroy(&share->cond);
258
hash_free(&share->name_hash);
260
plugin_unlock(NULL, share->db_plugin);
261
share->db_plugin= NULL;
263
/* We must copy mem_root from share because share is allocated through it */
264
memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
265
free_root(&mem_root, MYF(0)); // Free's share
270
Read table definition from a binary / text based .frm file
275
share Fill this with table definition
276
db_flags Bit mask of the following flags: OPEN_VIEW
279
This function is called when the table definition is not cached in
281
The data is returned in 'share', which is alloced by
282
alloc_table_share().. The code assumes that share is initialized.
286
1 Error (see open_table_error)
287
2 Error (see open_table_error)
288
3 Wrong data in .frm file
289
4 Error (see open_table_error)
290
5 Error (see open_table_error: charset unavailable)
291
6 Unknown .frm version
294
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags __attribute__((unused)))
296
int error, table_type;
299
uchar head[64], *disk_buff;
300
char path[FN_REFLEN];
301
MEM_ROOT **root_ptr, *old_root;
307
strxmov(path, share->normalized_path.str, reg_ext, NullS);
308
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
311
We don't try to open 5.0 unencoded name, if
312
- non-encoded name contains '@' signs,
313
because '@' can be misinterpreted.
314
It is not clear if '@' is escape character in 5.1,
315
or a normal character in 5.0.
317
- non-encoded db or table name contain "#mysql50#" prefix.
318
This kind of tables must have been opened only by the
321
if (strchr(share->table_name.str, '@') ||
322
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
323
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
324
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
325
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
328
/* Try unencoded 5.0 name */
330
strxnmov(path, sizeof(path)-1,
331
mysql_data_home, "/", share->db.str, "/",
332
share->table_name.str, reg_ext, NullS);
333
length= unpack_filename(path, path) - reg_ext_length;
335
The following is a safety test and should never fail
336
as the old file name should never be longer than the new one.
338
assert(length <= share->normalized_path.length);
340
If the old and the new names have the same length,
341
then table name does not have tricky characters,
342
so no need to check the old file name.
344
if (length == share->normalized_path.length ||
345
((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
348
/* Unencoded 5.0 table name found */
349
path[length]= '\0'; // Remove .frm extension
350
stpcpy(share->normalized_path.str, path);
351
share->normalized_path.length= length;
355
if (my_read(file, head, 64, MYF(MY_NABP)))
358
if (head[0] == (uchar) 254 && head[1] == 1)
360
if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
361
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
367
error= 6; // Unkown .frm version
374
/* No handling of text based files yet */
377
root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
379
*root_ptr= &share->mem_root;
380
error= open_binary_frm(thd, share, head, file);
387
share->table_category= get_table_category(& share->db, & share->table_name);
390
thd->status_var.opened_shares++;
393
my_close(file, MYF(MY_WME));
396
if (error && !error_given)
399
open_table_error(share, error, (share->open_errno= my_errno), 0);
407
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
410
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
413
int error, errarg= 0;
414
uint new_frm_ver, field_pack_length, new_field_pack_flag;
415
uint interval_count, interval_parts, read_length, int_length;
416
uint db_create_options, keys, key_parts, n_length;
417
uint key_info_length, com_length, null_bit_pos=0;
418
uint extra_rec_buf_length;
422
char *keynames, *names, *comment_pos;
424
uchar *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
425
ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
handler *handler_file= 0;
428
KEY_PART_INFO *key_part;
429
Field **field_ptr, *reg_field;
430
const char **interval_array;
431
enum legacy_db_type legacy_db_type;
432
my_bitmap_map *bitmaps;
434
uchar *field_extra_info= 0;
436
new_field_pack_flag= head[27];
437
new_frm_ver= (head[2] - FRM_VER);
438
field_pack_length= new_frm_ver < 2 ? 11 : 17;
442
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
443
goto err; /* purecov: inspected */
444
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
445
if (my_read(file,forminfo,288,MYF(MY_NABP)))
448
share->frm_version= head[2];
450
Check if .frm file created by MySQL 5.0. In this case we want to
451
display CHAR fields as CHAR and not as VARCHAR.
452
We do it this way as we want to keep the old frm version to enable
453
MySQL 4.1 to read these files.
455
if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
456
share->frm_version= FRM_VER_TRUE_VARCHAR;
458
legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
459
assert(share->db_plugin == NULL);
461
if the storage engine is dynamic, no point in resolving it by its
462
dynamically allocated legacy_db_type. We will resolve it later by name.
464
if (legacy_db_type > DB_TYPE_UNKNOWN &&
465
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
466
share->db_plugin= ha_lock_engine(NULL,
467
ha_checktype(thd, legacy_db_type, 0, 0));
468
share->db_create_options= db_create_options= uint2korr(head+30);
469
share->db_options_in_use= share->db_create_options;
470
share->mysql_version= uint4korr(head+51);
471
share->null_field_first= 0;
472
if (!head[32]) // New frm file in 3.23
474
share->avg_row_length= uint4korr(head+34);
475
share->transactional= (ha_choice) (head[39] & 3);
476
share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
477
share->row_type= (row_type) head[40];
478
share->block_size= uint4korr(head+43);
479
share->table_charset= get_charset((uint) head[38],MYF(0));
480
share->null_field_first= 1;
482
if (!share->table_charset)
484
/* unknown charset in head[38] or pre-3.23 frm */
485
if (use_mb(default_charset_info))
487
/* Warn that we may be changing the size of character columns */
488
sql_print_warning(_("'%s' had no or invalid character set, "
489
"and default character set is multi-byte, "
490
"so character column sizes may have changed"),
493
share->table_charset= default_charset_info;
495
share->db_record_offset= 1;
496
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
497
share->blob_ptr_size= portable_sizeof_char_ptr;
498
/* Set temporarily a good value for db_low_byte_first */
499
share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM);
501
share->max_rows= uint4korr(head+18);
502
share->min_rows= uint4korr(head+22);
504
/* Read keyinformation */
505
key_info_length= (uint) uint2korr(head+28);
506
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
507
if (read_string(file,(uchar**) &disk_buff,key_info_length))
508
goto err; /* purecov: inspected */
509
if (disk_buff[0] & 0x80)
511
share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
512
share->key_parts= key_parts= uint2korr(disk_buff+2);
516
share->keys= keys= disk_buff[0];
517
share->key_parts= key_parts= disk_buff[1];
519
share->keys_for_keyread.init(0);
520
share->keys_in_use.init(keys);
522
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
523
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
524
n_length + uint2korr(disk_buff+4))))
525
goto err; /* purecov: inspected */
526
memset(keyinfo, 0, n_length);
527
share->key_info= keyinfo;
528
key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
531
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
532
sizeof(ulong*)*key_parts)))
535
for (i=0 ; i < keys ; i++, keyinfo++)
537
keyinfo->table= 0; // Updated in open_frm
538
if (new_frm_ver >= 3)
540
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
541
keyinfo->key_length= (uint) uint2korr(strpos+2);
542
keyinfo->key_parts= (uint) strpos[4];
543
keyinfo->algorithm= (enum ha_key_alg) strpos[5];
544
keyinfo->block_size= uint2korr(strpos+6);
548
keyinfo->key_part= key_part;
549
keyinfo->rec_per_key= rec_per_key;
550
for (j=keyinfo->key_parts ; j-- ; key_part++)
553
key_part->fieldnr= (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
554
key_part->offset= (uint) uint2korr(strpos+2)-1;
555
key_part->key_type= (uint) uint2korr(strpos+5);
556
// key_part->field= (Field*) 0; // Will be fixed later
557
if (new_frm_ver >= 1)
559
key_part->key_part_flag= *(strpos+4);
560
key_part->length= (uint) uint2korr(strpos+7);
565
key_part->length= *(strpos+4);
566
key_part->key_part_flag=0;
567
if (key_part->length > 128)
569
key_part->length&=127; /* purecov: inspected */
570
key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
574
key_part->store_length=key_part->length;
577
keynames=(char*) key_part;
578
strpos+= (stpcpy(keynames, (char *) strpos) - keynames)+1;
580
//reading index comments
581
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
583
if (keyinfo->flags & HA_USES_COMMENT)
585
keyinfo->comment.length= uint2korr(strpos);
586
keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
587
keyinfo->comment.length);
588
strpos+= 2 + keyinfo->comment.length;
590
assert(test(keyinfo->flags & HA_USES_COMMENT) ==
591
(keyinfo->comment.length > 0));
594
share->reclength = uint2korr((head+16));
596
record_offset= (ulong) (uint2korr(head+6)+
597
((uint2korr(head+14) == 0xffff ?
598
uint4korr(head+47) : uint2korr(head+14))));
600
if ((n_length= uint4korr(head+55)))
602
/* Read extra data segment */
603
uchar *next_chunk, *buff_end;
604
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
606
if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
610
share->connect_string.length= uint2korr(buff);
611
if (!(share->connect_string.str= strmake_root(&share->mem_root,
612
(char*) next_chunk + 2,
613
share->connect_string.
618
next_chunk+= share->connect_string.length + 2;
619
buff_end= buff + n_length;
620
if (next_chunk + 2 < buff_end)
622
uint str_db_type_length= uint2korr(next_chunk);
624
name.str= (char*) next_chunk + 2;
625
name.length= str_db_type_length;
627
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
628
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
630
if (legacy_db_type > DB_TYPE_UNKNOWN &&
631
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
632
legacy_db_type != ha_legacy_type(
633
plugin_data(tmp_plugin, handlerton *)))
635
/* bad file, legacy_db_type did not match the name */
636
my_free(buff, MYF(0));
640
tmp_plugin is locked with a local lock.
641
we unlock the old value of share->db_plugin before
642
replacing it with a globally locked version of tmp_plugin
644
plugin_unlock(NULL, share->db_plugin);
645
share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
647
else if (!tmp_plugin)
649
/* purecov: begin inspected */
651
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
652
my_free(buff, MYF(0));
656
next_chunk+= str_db_type_length + 2;
658
if (share->mysql_version >= 50110)
660
/* New auto_partitioned indicator introduced in 5.1.11 */
663
if (forminfo[46] == (uchar)255)
665
//reading long table comment
666
if (next_chunk + 2 > buff_end)
668
my_free(buff, MYF(0));
671
share->comment.length = uint2korr(next_chunk);
672
if (! (share->comment.str= strmake_root(&share->mem_root,
673
(char*)next_chunk + 2, share->comment.length)))
675
my_free(buff, MYF(0));
678
next_chunk+= 2 + share->comment.length;
680
assert(next_chunk <= buff_end);
681
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
684
New frm format in mysql_version 5.2.5 (originally in
685
mysql-5.1.22-ndb-6.2.5)
686
New column properties added:
687
COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
688
TABLESPACE name is now stored in frm
690
if (next_chunk >= buff_end)
692
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
699
const uint format_section_header_size= 8;
700
uint format_section_len= uint2korr(next_chunk+0);
702
field_extra_info= next_chunk + format_section_header_size + 1;
703
next_chunk+= format_section_len;
706
assert (next_chunk <= buff_end);
707
if (next_chunk > buff_end)
712
share->key_block_size= uint2korr(head+62);
715
extra_rec_buf_length= uint2korr(head+59);
716
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
717
share->rec_buff_length= rec_buff_length;
718
if (!(record= (uchar *) alloc_root(&share->mem_root,
720
goto err; /* purecov: inspected */
721
share->default_values= record;
722
if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
723
goto err; /* purecov: inspected */
725
VOID(my_seek(file,pos+288,MY_SEEK_SET,MYF(0)));
727
share->fields= uint2korr(forminfo+258);
728
pos= uint2korr(forminfo+260); /* Length of all screens */
729
n_length= uint2korr(forminfo+268);
730
interval_count= uint2korr(forminfo+270);
731
interval_parts= uint2korr(forminfo+272);
732
int_length= uint2korr(forminfo+274);
733
share->null_fields= uint2korr(forminfo+282);
734
com_length= uint2korr(forminfo+284);
735
if (forminfo[46] != (uchar)255)
737
share->comment.length= (int) (forminfo[46]);
738
share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
share->comment.length);
743
if (!(field_ptr = (Field **)
744
alloc_root(&share->mem_root,
745
(uint) ((share->fields+1)*sizeof(Field*)+
746
interval_count*sizeof(TYPELIB)+
747
(share->fields+interval_parts+
748
keys+3)*sizeof(char *)+
749
(n_length+int_length+com_length)))))
750
goto err; /* purecov: inspected */
752
share->field= field_ptr;
753
read_length=(uint) (share->fields * field_pack_length +
754
pos+ (uint) (n_length+int_length+com_length));
755
if (read_string(file,(uchar**) &disk_buff,read_length))
756
goto err; /* purecov: inspected */
757
strpos= disk_buff+pos;
759
share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
760
interval_array= (const char **) (share->intervals+interval_count);
761
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
763
share->intervals= 0; // For better debugging
764
memcpy(names, strpos+(share->fields*field_pack_length),
765
(uint) (n_length+int_length));
766
comment_pos= names+(n_length+int_length);
767
memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
769
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
770
if (share->fieldnames.count != share->fields)
772
fix_type_pointers(&interval_array, share->intervals, interval_count,
776
/* Set ENUM and SET lengths */
778
for (interval= share->intervals;
779
interval < share->intervals + interval_count;
782
uint count= (uint) (interval->count + 1) * sizeof(uint);
783
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
786
for (count= 0; count < interval->count; count++)
788
char *val= (char*) interval->type_names[count];
789
interval->type_lengths[count]= strlen(val);
791
interval->type_lengths[count]= 0;
796
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
798
/* Allocate handler */
799
if (!(handler_file= get_new_handler(share, thd->mem_root,
803
record= share->default_values-1; /* Fieldstart = 1 */
804
if (share->null_field_first)
806
null_flags= null_pos= (uchar*) record+1;
807
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
809
null_bytes below is only correct under the condition that
810
there are no bit fields. Correct values is set below after the
811
table struct is initialized
813
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
816
use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
818
use_hash= !hash_init(&share->name_hash,
821
(hash_get_key) get_field_name,0,0);
823
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
825
uint pack_flag, interval_nr, unireg_type, recpos, field_length;
826
enum_field_types field_type;
827
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
const CHARSET_INFO *charset= NULL;
831
if (field_extra_info)
833
char tmp= field_extra_info[i];
834
column_format= (enum column_format_type)
835
((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
837
if (new_frm_ver >= 3)
839
/* new frm file in 4.1 */
840
field_length= uint2korr(strpos+3);
841
recpos= uint3korr(strpos+5);
842
pack_flag= uint2korr(strpos+8);
843
unireg_type= (uint) strpos[10];
844
interval_nr= (uint) strpos[12];
845
uint comment_length=uint2korr(strpos+15);
846
field_type=(enum_field_types) (uint) strpos[13];
850
charset= &my_charset_bin;
851
else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
853
error= 5; // Unknown or unavailable charset
854
errarg= (int) strpos[14];
860
comment.str= (char*) "";
865
comment.str= (char*) comment_pos;
866
comment.length= comment_length;
867
comment_pos+= comment_length;
872
field_length= (uint) strpos[3];
873
recpos= uint2korr(strpos+4),
874
pack_flag= uint2korr(strpos+6);
875
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
876
unireg_type= (uint) strpos[8];
877
interval_nr= (uint) strpos[10];
880
field_type= (enum_field_types) f_packtype(pack_flag);
881
if (f_is_binary(pack_flag))
884
Try to choose the best 4.1 type:
885
- for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
886
try to find a binary collation for character set.
887
- for other types (e.g. BLOB) just use my_charset_bin.
889
if (!f_is_blob(pack_flag))
891
// 3.23 or 4.0 string
892
if (!(charset= get_charset_by_csname(share->table_charset->csname,
893
MY_CS_BINSORT, MYF(0))))
894
charset= &my_charset_bin;
897
charset= &my_charset_bin;
900
charset= share->table_charset;
901
memset(&comment, 0, sizeof(comment));
904
if (interval_nr && charset->mbminlen > 1)
906
/* Unescape UCS2 intervals from HEX notation */
907
TYPELIB *interval= share->intervals + interval_nr - 1;
908
unhex_type2(interval);
911
*field_ptr= reg_field=
912
make_field(share, record+recpos,
913
(uint32_t) field_length,
914
null_pos, null_bit_pos,
918
(Field::utype) MTYP_TYPENR(unireg_type),
920
share->intervals+interval_nr-1 :
922
share->fieldnames.type_names[i]);
923
if (!reg_field) // Not supported field type
926
goto err; /* purecov: inspected */
929
reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
930
reg_field->field_index= i;
931
reg_field->comment=comment;
932
if (!(reg_field->flags & NOT_NULL_FLAG))
934
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
937
if (f_no_default(pack_flag))
938
reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
940
if (reg_field->unireg_check == Field::NEXT_NUMBER)
941
share->found_next_number_field= field_ptr;
942
if (share->timestamp_field == reg_field)
943
share->timestamp_field_offset= i;
946
(void) my_hash_insert(&share->name_hash,
947
(uchar*) field_ptr); // never fail
949
*field_ptr=0; // End marker
951
/* Fix key->name and key_part->field */
954
uint primary_key=(uint) (find_type((char*) primary_key_name,
955
&share->keynames, 3) - 1);
956
int64_t ha_option= handler_file->ha_table_flags();
957
keyinfo= share->key_info;
958
key_part= keyinfo->key_part;
960
for (uint key=0 ; key < share->keys ; key++,keyinfo++)
962
uint usable_parts= 0;
963
keyinfo->name=(char*) share->keynames.type_names[key];
965
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
968
If the UNIQUE key doesn't have NULL columns and is not a part key
969
declare this as a primary key.
972
for (i=0 ; i < keyinfo->key_parts ;i++)
974
uint fieldnr= key_part[i].fieldnr;
976
share->field[fieldnr-1]->null_ptr ||
977
share->field[fieldnr-1]->key_length() !=
980
primary_key=MAX_KEY; // Can't be used
986
for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
989
if (new_field_pack_flag <= 1)
990
key_part->fieldnr= (uint16_t) find_field(share->field,
991
share->default_values,
992
(uint) key_part->offset,
993
(uint) key_part->length);
994
if (!key_part->fieldnr)
996
error= 4; // Wrong file
999
field= key_part->field= share->field[key_part->fieldnr-1];
1000
key_part->type= field->key_type();
1001
if (field->null_ptr)
1003
key_part->null_offset=(uint) ((uchar*) field->null_ptr -
1004
share->default_values);
1005
key_part->null_bit= field->null_bit;
1006
key_part->store_length+=HA_KEY_NULL_LENGTH;
1007
keyinfo->flags|=HA_NULL_PART_KEY;
1008
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1009
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1011
if (field->type() == DRIZZLE_TYPE_BLOB ||
1012
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1014
if (field->type() == DRIZZLE_TYPE_BLOB)
1015
key_part->key_part_flag|= HA_BLOB_PART;
1017
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1018
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1019
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1020
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1022
if (i == 0 && key != primary_key)
1023
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1024
(keyinfo->key_parts == 1)) ?
1025
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1027
field->key_start.set_bit(key);
1028
if (field->key_length() == key_part->length &&
1029
!(field->flags & BLOB_FLAG))
1031
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1033
share->keys_for_keyread.set_bit(key);
1034
field->part_of_key.set_bit(key);
1035
field->part_of_key_not_clustered.set_bit(key);
1037
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1038
field->part_of_sortkey.set_bit(key);
1040
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1042
usable_parts++; // For FILESORT
1043
field->flags|= PART_KEY_FLAG;
1044
if (key == primary_key)
1046
field->flags|= PRI_KEY_FLAG;
1048
If this field is part of the primary key and all keys contains
1049
the primary key, then we can use any key to find this column
1051
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1053
field->part_of_key= share->keys_in_use;
1054
if (field->part_of_sortkey.is_set(key))
1055
field->part_of_sortkey= share->keys_in_use;
1058
if (field->key_length() != key_part->length)
1060
key_part->key_part_flag|= HA_PART_KEY_SEG;
1063
keyinfo->usable_key_parts= usable_parts; // Filesort
1065
set_if_bigger(share->max_key_length,keyinfo->key_length+
1066
keyinfo->key_parts);
1067
share->total_key_length+= keyinfo->key_length;
1069
MERGE tables do not have unique indexes. But every key could be
1070
an unique index on the underlying MyISAM table. (Bug #10400)
1072
if ((keyinfo->flags & HA_NOSAME) ||
1073
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1074
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1076
if (primary_key < MAX_KEY &&
1077
(share->keys_in_use.is_set(primary_key)))
1079
share->primary_key= primary_key;
1081
If we are using an integer as the primary key then allow the user to
1082
refer to it as '_rowid'
1084
if (share->key_info[primary_key].key_parts == 1)
1086
Field *field= share->key_info[primary_key].key_part[0].field;
1087
if (field && field->result_type() == INT_RESULT)
1089
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1090
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1096
share->primary_key = MAX_KEY; // we do not have a primary key
1099
share->primary_key= MAX_KEY;
1100
x_free((uchar*) disk_buff);
1102
if (new_field_pack_flag <= 1)
1104
/* Old file format with default as not null */
1105
uint null_length= (share->null_fields+7)/8;
1106
memset(share->default_values + (null_flags - (uchar*) record),
1110
if (share->found_next_number_field)
1112
reg_field= *share->found_next_number_field;
1113
if ((int) (share->next_number_index= (uint)
1114
find_ref_key(share->key_info, share->keys,
1115
share->default_values, reg_field,
1116
&share->next_number_key_offset,
1117
&share->next_number_keypart)) < 0)
1119
/* Wrong field definition */
1124
reg_field->flags |= AUTO_INCREMENT_FLAG;
1127
if (share->blob_fields)
1132
/* Store offsets to blob fields to find them fast */
1133
if (!(share->blob_field= save=
1134
(uint*) alloc_root(&share->mem_root,
1135
(uint) (share->blob_fields* sizeof(uint)))))
1137
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1139
if ((*ptr)->flags & BLOB_FLAG)
1145
the correct null_bytes can now be set, since bitfields have been taken
1148
share->null_bytes= (null_pos - (uchar*) null_flags +
1149
(null_bit_pos + 7) / 8);
1150
share->last_null_bit_pos= null_bit_pos;
1152
share->db_low_byte_first= handler_file->low_byte_first();
1153
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1155
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1156
share->column_bitmap_size)))
1158
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1159
bitmap_set_all(&share->all_set);
1161
delete handler_file;
1163
my_free(buff, MYF(0));
1168
my_free(buff, MYF(0));
1169
share->error= error;
1170
share->open_errno= my_errno;
1171
share->errarg= errarg;
1172
x_free((uchar*) disk_buff);
1173
delete handler_file;
1174
hash_free(&share->name_hash);
1176
open_table_error(share, error, share->open_errno, errarg);
1178
} /* open_binary_frm */
1182
Open a table based on a TABLE_SHARE
1185
open_table_from_share()
1187
share Table definition
1188
alias Alias for table
1189
db_stat open flags (for example HA_OPEN_KEYFILE|
1190
HA_OPEN_RNDFILE..) can be 0 (example in
1192
prgflag READ_ALL etc..
1193
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1194
outparam result table
1195
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1196
if OTM_CREATE some errors are ignore
1197
if OTM_ALTER HA_OPEN is not called
1201
1 Error (see open_table_error)
1202
2 Error (see open_table_error)
1203
3 Wrong data in .frm file
1204
4 Error (see open_table_error)
1205
5 Error (see open_table_error: charset unavailable)
1206
7 Table definition has changed in engine
1209
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1210
uint db_stat, uint prgflag, uint ha_open_flags,
1211
Table *outparam, open_table_mode open_mode)
1214
uint records, i, bitmap_size;
1215
bool error_reported= false;
1216
uchar *record, *bitmaps;
1219
/* Parsing of partitioning information from .frm needs thd->lex set up. */
1220
assert(thd->lex->is_lex_started);
1223
memset(outparam, 0, sizeof(*outparam));
1224
outparam->in_use= thd;
1226
outparam->db_stat= db_stat;
1227
outparam->write_row_record= NULL;
1229
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1231
if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
1233
outparam->quick_keys.init();
1234
outparam->covering_keys.init();
1235
outparam->keys_in_use_for_query.init();
1237
/* Allocate handler */
1239
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1241
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1251
outparam->reginfo.lock_type= TL_UNLOCK;
1252
outparam->current_lock= F_UNLCK;
1254
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1256
if (prgflag & (READ_ALL+EXTRA_RECORD))
1259
if (!(record= (uchar*) alloc_root(&outparam->mem_root,
1260
share->rec_buff_length * records)))
1261
goto err; /* purecov: inspected */
1265
/* We are probably in hard repair, and the buffers should not be used */
1266
outparam->record[0]= outparam->record[1]= share->default_values;
1270
outparam->record[0]= record;
1272
outparam->record[1]= record+ share->rec_buff_length;
1274
outparam->record[1]= outparam->record[0]; // Safety
1279
We need this because when we read var-length rows, we are not updating
1280
bytes after end of varchar
1284
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1285
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1287
memcpy(outparam->record[1], share->default_values,
1288
share->rec_buff_length);
1292
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1293
(uint) ((share->fields+1)*
1295
goto err; /* purecov: inspected */
1297
outparam->field= field_ptr;
1299
record= (uchar*) outparam->record[0]-1; /* Fieldstart = 1 */
1300
if (share->null_field_first)
1301
outparam->null_flags= (uchar*) record+1;
1303
outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
1306
/* Setup copy of fields from share, but use the right alias and record */
1307
for (i=0 ; i < share->fields; i++, field_ptr++)
1309
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1312
(*field_ptr)= 0; // End marker
1314
if (share->found_next_number_field)
1315
outparam->found_next_number_field=
1316
outparam->field[(uint) (share->found_next_number_field - share->field)];
1317
if (share->timestamp_field)
1318
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1321
/* Fix key->name and key_part->field */
1322
if (share->key_parts)
1324
KEY *key_info, *key_info_end;
1325
KEY_PART_INFO *key_part;
1327
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1328
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1330
outparam->key_info= key_info;
1331
key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
1333
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1334
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1337
for (key_info_end= key_info + share->keys ;
1338
key_info < key_info_end ;
1341
KEY_PART_INFO *key_part_end;
1343
key_info->table= outparam;
1344
key_info->key_part= key_part;
1346
for (key_part_end= key_part+ key_info->key_parts ;
1347
key_part < key_part_end ;
1350
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1352
if (field->key_length() != key_part->length &&
1353
!(field->flags & BLOB_FLAG))
1356
We are using only a prefix of the column as a key:
1357
Create a new field for the key part that matches the index
1359
field= key_part->field=field->new_field(&outparam->mem_root,
1361
field->field_length= key_part->length;
1367
/* Allocate bitmaps */
1369
bitmap_size= share->column_bitmap_size;
1370
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1372
bitmap_init(&outparam->def_read_set,
1373
(my_bitmap_map*) bitmaps, share->fields, false);
1374
bitmap_init(&outparam->def_write_set,
1375
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1376
bitmap_init(&outparam->tmp_set,
1377
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1378
outparam->default_column_bitmaps();
1380
/* The table struct is now initialized; Open the table */
1382
if (db_stat && open_mode != OTM_ALTER)
1385
if ((ha_err= (outparam->file->
1386
ha_open(outparam, share->normalized_path.str,
1387
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1388
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1389
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1390
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1391
HA_OPEN_ABORT_IF_LOCKED :
1392
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1394
/* Set a flag if the table is crashed and it can be auto. repaired */
1395
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1396
outparam->file->auto_repair() &&
1397
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1401
case HA_ERR_NO_SUCH_TABLE:
1403
The table did not exists in storage engine, use same error message
1404
as if the .frm file didn't exist
1411
Too many files opened, use same error message as if the .frm
1418
outparam->file->print_error(ha_err, MYF(0));
1419
error_reported= true;
1420
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1424
goto err; /* purecov: inspected */
1428
#if defined(HAVE_purify)
1429
memset(bitmaps, 0, bitmap_size*3);
1432
outparam->no_replicate= outparam->file &&
1433
test(outparam->file->ha_table_flags() &
1434
HA_HAS_OWN_BINLOGGING);
1435
thd->status_var.opened_tables++;
1440
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1441
open_table_error(share, error, my_errno, 0);
1442
delete outparam->file;
1443
outparam->file= 0; // For easier error checking
1444
outparam->db_stat=0;
1445
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1446
my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
1452
Free information allocated by openfrm
1456
table Table object to free
1457
free_share Is 1 if we also want to free table_share
1460
int closefrm(register Table *table, bool free_share)
1465
error=table->file->close();
1466
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
1470
for (Field **ptr=table->field ; *ptr ; ptr++)
94
cursor= 0; /* For easier errorchecking */
1475
table->file= 0; /* For easier errorchecking */
1478
if (table->s->tmp_table == NO_TMP_TABLE)
1479
release_table_share(table->s, RELEASE_NORMAL);
1481
free_table_share(table->s);
106
mem_root.free_root(MYF(0));
110
void Table::resetTable(Session *session,
112
uint32_t db_stat_arg)
125
db_stat= db_stat_arg;
128
record[0]= (unsigned char *) NULL;
129
record[1]= (unsigned char *) NULL;
131
insert_values.clear();
133
next_number_field= NULL;
134
found_next_number_field= NULL;
135
timestamp_field= NULL;
137
pos_in_table_list= NULL;
147
derived_select_number= 0;
148
current_lock= F_UNLCK;
162
open_placeholder= false;
163
locked_by_name= false;
166
auto_increment_field_not_null= false;
167
alias_name_used= false;
170
quick_condition_rows= 0;
172
timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
177
covering_keys.reset();
182
keys_in_use_for_query.reset();
183
keys_in_use_for_group_by.reset();
184
keys_in_use_for_order_by.reset();
186
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
187
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
189
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
190
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
192
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1483
free_root(&table->mem_root, MYF(0));
197
1488
/* Deallocate temporary blob storage */
199
1490
void free_blobs(register Table *table)
202
1493
for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
206
((Field_blob*) table->getField(*ptr))->free();
211
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
213
TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
1496
((Field_blob*) table->field[*ptr])->free();
1500
/* Find where a form starts */
1501
/* if formname is NullS then only formnames is read */
1503
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
1505
uint a_length,names,length;
1509
names=uint2korr(head+8);
1510
a_length=(names+2)*sizeof(char *); /* Room for two extra */
1515
save_names->type_names=0; /* Clear if error */
1519
length=uint2korr(head+4);
1520
VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0)));
1521
if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
1523
my_read(file, buf+a_length, (size_t) (length+names*4),
1525
{ /* purecov: inspected */
1526
x_free((uchar*) buf); /* purecov: inspected */
1527
return(0L); /* purecov: inspected */
1529
pos= buf+a_length+length;
1530
ret_value=uint4korr(pos);
1535
my_free((uchar*) buf,MYF(0));
1538
memset(save_names, 0, sizeof(save_names));
1542
str=(char *) (buf+a_length);
1543
fix_type_pointers((const char ***) &buf,save_names,1,&str);
1550
Read string from a file with malloc
1553
We add an \0 at end of the read string to make reading of C strings easier
1556
int read_string(File file, uchar**to, size_t length)
1560
if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
1561
my_read(file, *to, length,MYF(MY_NABP)))
1563
x_free(*to); /* purecov: inspected */
1564
*to= 0; /* purecov: inspected */
1565
return(1); /* purecov: inspected */
1567
*((char*) *to+length)= '\0';
1572
/* Add a new form to a form file */
1574
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
1575
const char *newname)
1577
uint i,bufflength,maxlength,n_length,length,names;
1578
ulong endpos,newpos;
1579
uchar buff[IO_SIZE];
1582
length=(uint) strlen(newname)+1;
1583
n_length=uint2korr(fileinfo+4);
1584
maxlength=uint2korr(fileinfo+6);
1585
names=uint2korr(fileinfo+8);
1586
newpos=uint4korr(fileinfo+10);
1588
if (64+length+n_length+(names+1)*4 > maxlength)
1591
int4store(fileinfo+10,newpos);
1592
endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1593
bufflength= (uint) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */
1595
while (endpos > maxlength)
1597
VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
1598
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1600
VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1602
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1604
endpos-=bufflength; bufflength=IO_SIZE;
1606
memset(buff, 0, IO_SIZE); /* Null new block */
1607
VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
1608
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1610
maxlength+=IO_SIZE; /* Fix old ref */
1611
int2store(fileinfo+6,maxlength);
1612
for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
1615
endpos=uint4korr(pos)+IO_SIZE;
1616
int4store(pos,endpos);
1623
VOID(strxmov((char*) buff,"/",newname,"/",NullS));
1626
VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1627
VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
1628
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1629
(names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
1630
names*4, MYF(MY_NABP+MY_WME))) ||
1631
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1632
return(0L); /* purecov: inspected */
1634
int2store(fileinfo+8,names+1);
1635
int2store(fileinfo+4,n_length+length);
1636
(void)ftruncate(file, newpos);/* Append file with '\0' */
1638
} /* make_new_entry */
1641
/* error message when opening a form file */
1643
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1646
char buff[FN_REFLEN];
1647
myf errortype= ME_ERROR+ME_WAITTANG;
1652
if (db_errno == ENOENT)
1653
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1656
strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1657
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1658
errortype, buff, db_errno);
1664
const char *datext= "";
1666
if (share->db_type() != NULL)
1668
if ((file= get_new_handler(share, current_thd->mem_root,
1671
if (!(datext= *file->bas_ext()))
1675
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1676
ER_FILE_USED : ER_CANT_OPEN_FILE;
1677
strxmov(buff, share->normalized_path.str, datext, NullS);
1678
my_error(err_no,errortype, buff, db_errno);
1684
const char *csname= get_charset_name((uint) errarg);
1686
if (!csname || csname[0] =='?')
1688
snprintf(tmp, sizeof(tmp), "#%d", errarg);
1691
my_printf_error(ER_UNKNOWN_COLLATION,
1692
_("Unknown collation '%s' in table '%-.64s' definition"),
1693
MYF(0), csname, share->table_name.str);
1697
strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1698
my_printf_error(ER_NOT_FORM_FILE,
1699
_("Table '%-.64s' was created with a different version "
1700
"of MySQL and cannot be read"),
1705
default: /* Better wrong error than none */
1707
strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1708
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1712
} /* open_table_error */
1716
** fix a str_type to a array type
1717
** typeparts separated with some char. differents types are separated
1722
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
1725
char *type_name, *ptr;
1731
point_to_type->name=0;
1732
point_to_type->type_names= *array;
1734
if ((chr= *ptr)) /* Test if empty type */
1736
while ((type_name=strchr(ptr+1,chr)) != NullS)
1738
*((*array)++) = ptr+1;
1739
*type_name= '\0'; /* End string */
1742
ptr+=2; /* Skip end mark and last 0 */
1746
point_to_type->count= (uint) (*array - point_to_type->type_names);
1748
*((*array)++)= NullS; /* End of type */
1750
*names=ptr; /* Update end */
1752
} /* fix_type_pointers */
1755
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1757
TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
216
result->count= strings.elements;
218
uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
220
if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
1760
result->count=strings.elements;
1762
uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1763
if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
223
1765
result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
1766
List_iterator<String> it(strings);
227
for (uint32_t i= 0; (tmp= it++); i++)
1768
for (uint i=0; (tmp=it++) ; i++)
229
1770
result->type_names[i]= tmp->ptr();
230
1771
result->type_lengths[i]= tmp->length();
233
result->type_names[result->count]= 0; // End marker
1773
result->type_names[result->count]= 0; // End marker
234
1774
result->type_lengths[result->count]= 0;
1780
Search after a field with given start & length
1781
If an exact field isn't found, return longest field with starts
1785
This is needed because in some .frm fields 'fieldnr' was saved wrong
1792
static uint find_field(Field **fields, uchar *record, uint start, uint length)
1798
for (field= fields, i=1 ; *field ; i++,field++)
1800
if ((*field)->offset(record) == start)
1802
if ((*field)->key_length() == length)
1804
if (!pos || fields[pos-1]->pack_length() <
1805
(*field)->pack_length())
239
1813
/* Check that the integer is in the internal */
241
1815
int set_zone(register int nr, int min_zone, int max_zone)
1373
4198
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1374
4199
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1375
4200
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
4201
0 : FIELDFLAG_BINARY;
1380
if (session->is_fatal_error) // If end of memory
1382
table->getMutableShare()->db_record_offset= 1;
1383
if (table->getShare()->db_type() == myisam_engine)
4205
if (thd->is_fatal_error) // If end of memory
4206
goto err; /* purecov: inspected */
4207
share->db_record_offset= 1;
4208
if (share->db_type() == myisam_hton)
1385
4210
if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
4211
¶m->recinfo, select_options))
1389
assert(table->in_use);
1390
4214
if (table->open_tmp_table())
1393
session->mem_root= mem_root_save;
4217
thd->mem_root= mem_root_save;
1398
session->mem_root= mem_root_save;
4222
thd->mem_root= mem_root_save;
4223
table->free_tmp_table(thd); /* purecov: inspected */
4224
if (temp_pool_slot != MY_BIT_NONE)
4225
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4226
return(NULL); /* purecov: inspected */
1404
4229
/****************************************************************************/
1406
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
boost::dynamic_bitset<>& write_set_arg)
1409
read_set= &read_set_arg;
1410
write_set= &write_set_arg;
1414
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1416
const boost::dynamic_bitset<> old= in_map;
1417
in_map= getShare()->all_set;
4232
Create a reduced Table object with properly set up Field list from a
4233
list of field definitions.
4235
The created table doesn't have a table handler associated with
4236
it, has no keys, no group/distinct, no copy_funcs array.
4237
The sole purpose of this Table object is to use the power of Field
4238
class to read/write data to/from table->record[0]. Then one can store
4239
the record in any container (RB tree, hash, etc).
4240
The table is created in THD mem_root, so are the table's fields.
4241
Consequently, if you don't BLOB fields, you don't need to free it.
4243
@param thd connection handle
4244
@param field_list list of column definitions
4247
0 if out of memory, Table object in case of success
4250
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
4252
uint field_count= field_list.elements;
4255
Create_field *cdef; /* column definition */
4256
uint record_length= 0;
4257
uint null_count= 0; /* number of columns which may be null */
4258
uint null_pack_length; /* NULL representation array length */
4264
if (!multi_alloc_root(thd->mem_root,
4265
&table, sizeof(*table),
4266
&share, sizeof(*share),
4267
&field, (field_count + 1) * sizeof(Field*),
4268
&blob_field, (field_count+1) *sizeof(uint),
4269
&bitmaps, bitmap_buffer_size(field_count)*2,
4273
memset(table, 0, sizeof(*table));
4274
memset(share, 0, sizeof(*share));
4275
table->field= field;
4277
share->blob_field= blob_field;
4278
share->fields= field_count;
4279
share->blob_ptr_size= portable_sizeof_char_ptr;
4280
table->setup_tmp_table_column_bitmaps(bitmaps);
4282
/* Create all fields and calculate the total length of record */
4283
List_iterator_fast<Create_field> it(field_list);
4284
while ((cdef= it++))
4286
*field= make_field(share, 0, cdef->length,
4287
(uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4288
f_maybe_null(cdef->pack_flag) ? 1 : 0,
4289
cdef->pack_flag, cdef->sql_type, cdef->charset,
4291
cdef->interval, cdef->field_name);
4294
(*field)->init(table);
4295
record_length+= (*field)->pack_length();
4296
if (! ((*field)->flags & NOT_NULL_FLAG))
4299
if ((*field)->flags & BLOB_FLAG)
4300
share->blob_field[blob_count++]= (uint) (field - table->field);
4304
*field= NULL; /* mark the end of the list */
4305
share->blob_field[blob_count]= 0; /* mark the end of the list */
4306
share->blob_fields= blob_count;
4308
null_pack_length= (null_count + 7)/8;
4309
share->reclength= record_length + null_pack_length;
4310
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4311
table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
4312
if (!table->record[0])
4315
if (null_pack_length)
4317
table->null_flags= (uchar*) table->record[0];
4318
share->null_fields= null_count;
4319
share->null_bytes= null_pack_length;
4322
table->in_use= thd; /* field->reset() may access table->in_use */
4324
/* Set up field pointers */
4325
uchar *null_pos= table->record[0];
4326
uchar *field_pos= null_pos + share->null_bytes;
4329
for (field= table->field; *field; ++field)
4331
Field *cur_field= *field;
4332
if ((cur_field->flags & NOT_NULL_FLAG))
4333
cur_field->move_field(field_pos);
4336
cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
4338
if (null_bit == (1 << 8))
4346
field_pos+= cur_field->pack_length();
4351
for (field= table->field; *field; ++field)
4352
delete *field; /* just invokes field destructor */
4357
bool Table::open_tmp_table()
4360
if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4361
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4363
file->print_error(error,MYF(0)); /* purecov: inspected */
4367
(void) file->extra(HA_EXTRA_QUICK); /* Faster */
4373
Create MyISAM temporary table
4376
create_myisam_tmp_table()
4377
keyinfo Description of the index (there is always one index)
4378
start_recinfo MyISAM's column descriptions
4379
recinfo INOUT End of MyISAM's column descriptions
4383
Create a MyISAM temporary table according to passed description. The is
4384
assumed to have one unique index or constraint.
4386
The passed array or MI_COLUMNDEF structures must have this form:
4388
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4389
when there are many nullable columns)
4391
3. One free MI_COLUMNDEF element (*recinfo points here)
4393
This function may use the free element to create hash column for unique
4401
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4402
MI_COLUMNDEF *start_recinfo,
4403
MI_COLUMNDEF **recinfo,
4408
MI_UNIQUEDEF uniquedef;
4409
TABLE_SHARE *share= s;
4412
{ // Get keys for ni_create
4413
bool using_unique_constraint=0;
4414
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4415
sizeof(*seg) * keyinfo->key_parts);
4419
memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4420
if (keyinfo->key_length >= file->max_key_length() ||
4421
keyinfo->key_parts > file->max_key_parts() ||
4424
/* Can't create a key; Make a unique constraint instead of a key */
4427
using_unique_constraint=1;
4428
memset(&uniquedef, 0, sizeof(uniquedef));
4429
uniquedef.keysegs=keyinfo->key_parts;
4431
uniquedef.null_are_equal=1;
4433
/* Create extra column for hash value */
4434
memset(*recinfo, 0, sizeof(**recinfo));
4435
(*recinfo)->type= FIELD_CHECK;
4436
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4438
share->reclength+=MI_UNIQUE_HASH_LENGTH;
4442
/* Create an unique key */
4443
memset(&keydef, 0, sizeof(keydef));
4444
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4445
keydef.keysegs= keyinfo->key_parts;
4448
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
4450
Field *field=keyinfo->key_part[i].field;
4452
seg->language= field->charset()->number;
4453
seg->length= keyinfo->key_part[i].length;
4454
seg->start= keyinfo->key_part[i].offset;
4455
if (field->flags & BLOB_FLAG)
4458
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4459
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4460
seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
4461
seg->flag= HA_BLOB_PART;
4462
seg->length=0; // Whole blob in unique constraint
4466
seg->type= keyinfo->key_part[i].type;
4468
if (!(field->flags & NOT_NULL_FLAG))
4470
seg->null_bit= field->null_bit;
4471
seg->null_pos= (uint) (field->null_ptr - (uchar*) record[0]);
4473
We are using a GROUP BY on something that contains NULL
4474
In this case we have to tell MyISAM that two NULL should
4475
on INSERT be regarded at the same value
4477
if (!using_unique_constraint)
4478
keydef.flag|= HA_NULL_ARE_EQUAL;
4482
MI_CREATE_INFO create_info;
4483
memset(&create_info, 0, sizeof(create_info));
4485
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4487
create_info.data_file_length= ~(uint64_t) 0;
4489
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4490
(uint) (*recinfo-start_recinfo),
4492
share->uniques, &uniquedef,
4494
HA_CREATE_TMP_TABLE)))
4496
file->print_error(error,MYF(0)); /* purecov: inspected */
4500
status_var_increment(in_use->status_var.created_tmp_disk_tables);
4501
share->db_record_offset= 1;
4508
void Table::free_tmp_table(THD *thd)
4510
MEM_ROOT own_root= mem_root;
4511
const char *save_proc_info;
4513
save_proc_info=thd->get_proc_info();
4514
thd_proc_info(thd, "removing tmp table");
4519
file->ha_drop_table(s->table_name.str);
4521
file->ha_delete_table(s->table_name.str);
4526
for (Field **ptr= field ; *ptr ; ptr++)
4528
free_io_cache(this);
4530
if (temp_pool_slot != MY_BIT_NONE)
4531
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4533
plugin_unlock(0, s->db_plugin);
4535
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4536
thd_proc_info(thd, save_proc_info);
4542
If a HEAP table gets full, create a MyISAM table and copy all rows
4546
bool create_myisam_from_heap(THD *thd, Table *table,
4547
MI_COLUMNDEF *start_recinfo,
4548
MI_COLUMNDEF **recinfo,
4549
int error, bool ignore_last_dupp_key_error)
4553
const char *save_proc_info;
4556
if (table->s->db_type() != heap_hton ||
4557
error != HA_ERR_RECORD_FILE_FULL)
4559
table->file->print_error(error,MYF(0));
4564
new_table.s= &share;
4565
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
4566
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4567
new_table.s->db_type())))
4568
return(1); // End of memory
4570
save_proc_info=thd->get_proc_info();
4571
thd_proc_info(thd, "converting HEAP to MyISAM");
4573
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4574
recinfo, thd->lex->select_lex.options |
4577
if (new_table.open_tmp_table())
4579
if (table->file->indexes_are_disabled())
4580
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4581
table->file->ha_index_or_rnd_end();
4582
table->file->ha_rnd_init(1);
4585
new_table.file->extra(HA_EXTRA_NO_ROWS);
4586
new_table.no_rows=1;
4589
#ifdef TO_BE_DONE_LATER_IN_4_1
4591
To use start_bulk_insert() (which is new in 4.1) we need to find
4592
all places where a corresponding end_bulk_insert() should be put.
4594
table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
4595
new_table.file->ha_start_bulk_insert(table->file->stats.records);
4597
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4598
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4602
copy all old rows from heap table to MyISAM table
4603
This is the only code that uses record[1] to read/write but this
4604
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4606
while (!table->file->rnd_next(new_table.record[1]))
4608
write_err= new_table.file->ha_write_row(new_table.record[1]);
4612
/* copy row that filled HEAP table */
4613
if ((write_err=new_table.file->ha_write_row(table->record[0])))
4615
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4616
!ignore_last_dupp_key_error)
4620
/* remove heap table and change to use myisam table */
4621
(void) table->file->ha_rnd_end();
4622
(void) table->file->close(); // This deletes the table !
4625
plugin_unlock(0, table->s->db_plugin);
4626
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4627
new_table.s= table->s; // Keep old share
4631
table->file->change_table_ptr(table, table->s);
4632
table->use_all_columns();
4635
const char *new_proc_info=
4636
(!strcmp(save_proc_info,"Copying to tmp table") ?
4637
"Copying to tmp table on disk" : save_proc_info);
4638
thd_proc_info(thd, new_proc_info);
4643
table->file->print_error(write_err, MYF(0));
4644
(void) table->file->ha_rnd_end();
4645
(void) new_table.file->close();
4647
new_table.file->ha_delete_table(new_table.s->table_name.str);
4649
delete new_table.file;
4650
thd_proc_info(thd, save_proc_info);
4651
table->mem_root= new_table.mem_root;
4655
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4657
my_bitmap_map *old= bitmap->bitmap;
4658
bitmap->bitmap= s->all_set.bitmap;
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4662
void Table::restore_column_map(my_bitmap_map *old)
1423
for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
4664
read_set->bitmap= old;
1436
uint32_t Table::find_shortest_key(const key_map *usable_keys)
4667
uint Table::find_shortest_key(const key_map *usable_keys)
1438
4669
uint32_t min_length= UINT32_MAX;
1439
4670
uint32_t best= MAX_KEY;
1440
if (usable_keys->any())
4671
if (!usable_keys->is_clear_all())
1442
for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
4673
for (uint nr=0; nr < s->keys ; nr++)
1444
if (usable_keys->test(nr))
4675
if (usable_keys->is_set(nr))
1446
4677
if (key_info[nr].key_length < min_length)