1
/* Copyright (C) 2000-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
/* Some general useful functions */
19
#include "mysql_priv.h"
23
/* INFORMATION_SCHEMA name */
24
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
26
/* MYSQL_SCHEMA name */
27
LEX_STRING MYSQL_SCHEMA_NAME= {C_STRING_WITH_LEN("mysql")};
29
/* Functions defined in this file */
31
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
32
myf errortype, int errarg);
33
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
34
uchar *head, File file);
35
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
36
uint types, char **names);
37
static uint find_field(Field **fields, uchar *record, uint start, uint length);
39
inline bool is_system_table_name(const char *name, uint length);
41
/**************************************************************************
42
Object_creation_ctx implementation.
43
**************************************************************************/
45
Object_creation_ctx *Object_creation_ctx::set_n_backup(THD *thd)
47
Object_creation_ctx *backup_ctx;
48
DBUG_ENTER("Object_creation_ctx::set_n_backup");
50
backup_ctx= create_backup_ctx(thd);
53
DBUG_RETURN(backup_ctx);
56
void Object_creation_ctx::restore_env(THD *thd, Object_creation_ctx *backup_ctx)
61
backup_ctx->change_env(thd);
66
/**************************************************************************
67
Default_object_creation_ctx implementation.
68
**************************************************************************/
70
Default_object_creation_ctx::Default_object_creation_ctx(THD *thd)
71
: m_client_cs(thd->variables.character_set_client),
72
m_connection_cl(thd->variables.collation_connection)
75
Default_object_creation_ctx::Default_object_creation_ctx(
76
CHARSET_INFO *client_cs, CHARSET_INFO *connection_cl)
77
: m_client_cs(client_cs),
78
m_connection_cl(connection_cl)
82
Default_object_creation_ctx::create_backup_ctx(THD *thd) const
84
return new Default_object_creation_ctx(thd);
87
void Default_object_creation_ctx::change_env(THD *thd) const
89
thd->variables.character_set_client= m_client_cs;
90
thd->variables.collation_connection= m_connection_cl;
92
thd->update_charset();
95
/*************************************************************************/
97
/* Get column name from column hash */
99
static uchar *get_field_name(Field **buff, size_t *length,
100
my_bool not_used __attribute__((unused)))
102
*length= (uint) strlen((*buff)->field_name);
103
return (uchar*) (*buff)->field_name;
108
Returns pointer to '.frm' extension of the file name.
115
Checks file name part starting with the rightmost '.' character,
116
and returns it if it is equal to '.frm'.
119
It is a good idea to get rid of this function modifying the code
120
to garantee that the functions presently calling fn_rext() always
121
get arguments in the same format: either with '.frm' or without '.frm'.
124
Pointer to the '.frm' extension. If there is no extension,
125
or extension is not '.frm', pointer at the end of file name.
128
char *fn_rext(char *name)
130
char *res= strrchr(name, '.');
131
if (res && !strcmp(res, reg_ext))
133
return name + strlen(name);
136
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
138
DBUG_ASSERT(db != NULL);
139
DBUG_ASSERT(name != NULL);
141
if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
142
(my_strcasecmp(system_charset_info,
143
INFORMATION_SCHEMA_NAME.str,
146
return TABLE_CATEGORY_INFORMATION;
149
if ((db->length == MYSQL_SCHEMA_NAME.length) &&
150
(my_strcasecmp(system_charset_info,
151
MYSQL_SCHEMA_NAME.str,
154
if (is_system_table_name(name->str, name->length))
156
return TABLE_CATEGORY_SYSTEM;
160
return TABLE_CATEGORY_USER;
165
Allocate a setup TABLE_SHARE structure
169
TABLE_LIST Take database and table name from there
170
key Table cache key (db \0 table_name \0...)
171
key_length Length of key
174
0 Error (out of memory)
178
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
183
char *key_buff, *path_buff;
184
char path[FN_REFLEN];
186
DBUG_ENTER("alloc_table_share");
187
DBUG_PRINT("enter", ("table: '%s'.'%s'",
188
table_list->db, table_list->table_name));
190
path_length= build_table_filename(path, sizeof(path) - 1,
192
table_list->table_name, "", 0);
193
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
194
if (multi_alloc_root(&mem_root,
195
&share, sizeof(*share),
196
&key_buff, key_length,
197
&path_buff, path_length + 1,
200
bzero((char*) share, sizeof(*share));
202
share->set_table_cache_key(key_buff, key, key_length);
204
share->path.str= path_buff;
205
share->path.length= path_length;
206
strmov(share->path.str, path);
207
share->normalized_path.str= share->path.str;
208
share->normalized_path.length= path_length;
210
share->version= refresh_version;
212
share->tablespace= NULL;
215
This constant is used to mark that no table map version has been
216
assigned. No arithmetic is done on the value: it will be
217
overwritten with a value taken from MYSQL_BIN_LOG.
219
share->table_map_version= ~(uint64_t)0;
222
Since alloc_table_share() can be called without any locking (for
223
example, ha_create_table... functions), we do not assign a table
224
map id here. Instead we assign a value that is not used
225
elsewhere, and then assign a table map id inside open_table()
226
under the protection of the LOCK_open mutex.
228
share->table_map_id= ~0UL;
229
share->cached_row_logging_check= -1;
231
memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
232
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
233
pthread_cond_init(&share->cond, NULL);
240
Initialize share for temporary tables
243
init_tmp_table_share()
246
key Table_cache_key, as generated from create_table_def_key.
247
must start with db name.
248
key_length Length of key
249
table_name Table name
250
path Path to file (possible in lower case) without .frm
253
This is different from alloc_table_share() because temporary tables
254
don't have to be shared between threads or put into the table def
255
cache, so we can do some things notable simpler and faster
257
If table is not put in thd->temporary_tables (happens only when
258
one uses OPEN TEMPORARY) then one can specify 'db' as key and
259
use key_length= 0 as neither table_cache_key or key_length will be used).
262
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
263
uint key_length, const char *table_name,
266
DBUG_ENTER("init_tmp_table_share");
267
DBUG_PRINT("enter", ("table: '%s'.'%s'", key, table_name));
269
bzero((char*) share, sizeof(*share));
270
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
271
share->table_category= TABLE_CATEGORY_TEMPORARY;
272
share->tmp_table= INTERNAL_TMP_TABLE;
273
share->db.str= (char*) key;
274
share->db.length= strlen(key);
275
share->table_cache_key.str= (char*) key;
276
share->table_cache_key.length= key_length;
277
share->table_name.str= (char*) table_name;
278
share->table_name.length= strlen(table_name);
279
share->path.str= (char*) path;
280
share->normalized_path.str= (char*) path;
281
share->path.length= share->normalized_path.length= strlen(path);
282
share->frm_version= FRM_VER_TRUE_VARCHAR;
283
share->tablespace= NULL;
285
Temporary tables are not replicated, but we set up these fields
286
anyway to be able to catch errors.
288
share->table_map_version= ~(uint64_t)0;
289
share->cached_row_logging_check= -1;
292
table_map_id is also used for MERGE tables to suppress repeated
293
compatibility checks.
295
share->table_map_id= (ulong) thd->query_id;
302
Free table share and memory used by it
309
share->mutex must be locked when we come here if it's not a temp table
312
void free_table_share(TABLE_SHARE *share)
315
DBUG_ENTER("free_table_share");
316
DBUG_PRINT("enter", ("table: %s.%s", share->db.str, share->table_name.str));
317
DBUG_ASSERT(share->ref_count == 0);
320
If someone is waiting for this to be deleted, inform it about this.
321
Don't do a delete until we know that no one is refering to this anymore.
323
if (share->tmp_table == NO_TMP_TABLE)
325
/* share->mutex is locked in release_table_share() */
326
while (share->waiting_on_cond)
328
pthread_cond_broadcast(&share->cond);
329
pthread_cond_wait(&share->cond, &share->mutex);
331
/* No thread refers to this anymore */
332
pthread_mutex_unlock(&share->mutex);
333
pthread_mutex_destroy(&share->mutex);
334
pthread_cond_destroy(&share->cond);
336
hash_free(&share->name_hash);
338
plugin_unlock(NULL, share->db_plugin);
339
share->db_plugin= NULL;
341
/* We must copy mem_root from share because share is allocated through it */
342
memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root));
343
free_root(&mem_root, MYF(0)); // Free's share
349
Return TRUE if a table name matches one of the system table names.
352
help_category, help_keyword, help_relation, help_topic,
354
time_zone, time_zone_leap_second, time_zone_name, time_zone_transition,
355
time_zone_transition_type
357
This function trades accuracy for speed, so may return false
358
positives. Presumably mysql.* database is for internal purposes only
359
and should not contain user tables.
362
inline bool is_system_table_name(const char *name, uint length)
364
CHARSET_INFO *ci= system_charset_info;
367
/* mysql.proc table */
370
my_tolower(ci, name[0]) == 'p' &&
371
my_tolower(ci, name[1]) == 'r' &&
372
my_tolower(ci, name[2]) == 'o' &&
373
my_tolower(ci, name[3]) == 'c'
376
/* one of mysql.help* tables */
379
my_tolower(ci, name[0]) == 'h' &&
380
my_tolower(ci, name[1]) == 'e' &&
381
my_tolower(ci, name[2]) == 'l' &&
382
my_tolower(ci, name[3]) == 'p'
385
/* one of mysql.time_zone* tables */
387
my_tolower(ci, name[0]) == 't' &&
388
my_tolower(ci, name[1]) == 'i' &&
389
my_tolower(ci, name[2]) == 'm' &&
390
my_tolower(ci, name[3]) == 'e'
397
Read table definition from a binary / text based .frm file
402
share Fill this with table definition
403
db_flags Bit mask of the following flags: OPEN_VIEW
406
This function is called when the table definition is not cached in
408
The data is returned in 'share', which is alloced by
409
alloc_table_share().. The code assumes that share is initialized.
413
1 Error (see open_table_error)
414
2 Error (see open_table_error)
415
3 Wrong data in .frm file
416
4 Error (see open_table_error)
417
5 Error (see open_table_error: charset unavailable)
418
6 Unknown .frm version
421
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
423
int error, table_type;
426
uchar head[64], *disk_buff;
427
char path[FN_REFLEN];
428
MEM_ROOT **root_ptr, *old_root;
429
DBUG_ENTER("open_table_def");
430
DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str,
431
share->table_name.str, share->normalized_path.str));
437
strxmov(path, share->normalized_path.str, reg_ext, NullS);
438
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
441
We don't try to open 5.0 unencoded name, if
442
- non-encoded name contains '@' signs,
443
because '@' can be misinterpreted.
444
It is not clear if '@' is escape character in 5.1,
445
or a normal character in 5.0.
447
- non-encoded db or table name contain "#mysql50#" prefix.
448
This kind of tables must have been opened only by the
451
if (strchr(share->table_name.str, '@') ||
452
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
453
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
454
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
455
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
458
/* Try unencoded 5.0 name */
460
strxnmov(path, sizeof(path)-1,
461
mysql_data_home, "/", share->db.str, "/",
462
share->table_name.str, reg_ext, NullS);
463
length= unpack_filename(path, path) - reg_ext_length;
465
The following is a safety test and should never fail
466
as the old file name should never be longer than the new one.
468
DBUG_ASSERT(length <= share->normalized_path.length);
470
If the old and the new names have the same length,
471
then table name does not have tricky characters,
472
so no need to check the old file name.
474
if (length == share->normalized_path.length ||
475
((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
478
/* Unencoded 5.0 table name found */
479
path[length]= '\0'; // Remove .frm extension
480
strmov(share->normalized_path.str, path);
481
share->normalized_path.length= length;
485
if (my_read(file, head, 64, MYF(MY_NABP)))
488
if (head[0] == (uchar) 254 && head[1] == 1)
490
if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
491
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
494
if (db_flags & OPEN_VIEW_ONLY)
503
error= 6; // Unkown .frm version
510
/* No handling of text based files yet */
513
root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
515
*root_ptr= &share->mem_root;
516
error= open_binary_frm(thd, share, head, file);
521
share->table_category= get_table_category(& share->db, & share->table_name);
524
thd->status_var.opened_shares++;
527
my_close(file, MYF(MY_WME));
530
if (error && !error_given)
533
open_table_error(share, error, (share->open_errno= my_errno), 0);
541
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
544
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
547
int error, errarg= 0;
548
uint new_frm_ver, field_pack_length, new_field_pack_flag;
549
uint interval_count, interval_parts, read_length, int_length;
550
uint db_create_options, keys, key_parts, n_length;
551
uint key_info_length, com_length, null_bit_pos;
552
uint extra_rec_buf_length;
556
char *keynames, *names, *comment_pos;
558
uchar *disk_buff, *strpos, *null_flags, *null_pos;
559
ulong pos, record_offset, *rec_per_key, rec_buff_length;
560
handler *handler_file= 0;
562
KEY_PART_INFO *key_part;
563
SQL_CRYPT *crypted=0;
564
Field **field_ptr, *reg_field;
565
const char **interval_array;
566
enum legacy_db_type legacy_db_type;
567
my_bitmap_map *bitmaps;
569
uchar *field_extra_info= 0;
570
DBUG_ENTER("open_binary_frm");
572
new_field_pack_flag= head[27];
573
new_frm_ver= (head[2] - FRM_VER);
574
field_pack_length= new_frm_ver < 2 ? 11 : 17;
578
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
579
goto err; /* purecov: inspected */
580
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
581
if (my_read(file,forminfo,288,MYF(MY_NABP)))
584
share->frm_version= head[2];
586
Check if .frm file created by MySQL 5.0. In this case we want to
587
display CHAR fields as CHAR and not as VARCHAR.
588
We do it this way as we want to keep the old frm version to enable
589
MySQL 4.1 to read these files.
591
if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
592
share->frm_version= FRM_VER_TRUE_VARCHAR;
594
legacy_db_type= (enum legacy_db_type) (uint) *(head+3);
595
DBUG_ASSERT(share->db_plugin == NULL);
597
if the storage engine is dynamic, no point in resolving it by its
598
dynamically allocated legacy_db_type. We will resolve it later by name.
600
if (legacy_db_type > DB_TYPE_UNKNOWN &&
601
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
602
share->db_plugin= ha_lock_engine(NULL,
603
ha_checktype(thd, legacy_db_type, 0, 0));
604
share->db_create_options= db_create_options= uint2korr(head+30);
605
share->db_options_in_use= share->db_create_options;
606
share->mysql_version= uint4korr(head+51);
607
share->null_field_first= 0;
608
if (!head[32]) // New frm file in 3.23
610
share->avg_row_length= uint4korr(head+34);
611
share->transactional= (ha_choice) (head[39] & 3);
612
share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
613
share->row_type= (row_type) head[40];
614
share->table_charset= get_charset((uint) head[38],MYF(0));
615
share->null_field_first= 1;
617
if (!share->table_charset)
619
/* unknown charset in head[38] or pre-3.23 frm */
620
if (use_mb(default_charset_info))
622
/* Warn that we may be changing the size of character columns */
623
sql_print_warning("'%s' had no or invalid character set, "
624
"and default character set is multi-byte, "
625
"so character column sizes may have changed",
628
share->table_charset= default_charset_info;
630
share->db_record_offset= 1;
631
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
632
share->blob_ptr_size= portable_sizeof_char_ptr;
633
/* Set temporarily a good value for db_low_byte_first */
634
share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM);
636
share->max_rows= uint4korr(head+18);
637
share->min_rows= uint4korr(head+22);
639
/* Read keyinformation */
640
key_info_length= (uint) uint2korr(head+28);
641
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
642
if (read_string(file,(uchar**) &disk_buff,key_info_length))
643
goto err; /* purecov: inspected */
644
if (disk_buff[0] & 0x80)
646
share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
647
share->key_parts= key_parts= uint2korr(disk_buff+2);
651
share->keys= keys= disk_buff[0];
652
share->key_parts= key_parts= disk_buff[1];
654
share->keys_for_keyread.init(0);
655
share->keys_in_use.init(keys);
657
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
658
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
659
n_length + uint2korr(disk_buff+4))))
660
goto err; /* purecov: inspected */
661
bzero((char*) keyinfo,n_length);
662
share->key_info= keyinfo;
663
key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
666
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
667
sizeof(ulong*)*key_parts)))
670
for (i=0 ; i < keys ; i++, keyinfo++)
672
keyinfo->table= 0; // Updated in open_frm
673
if (new_frm_ver >= 3)
675
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
676
keyinfo->key_length= (uint) uint2korr(strpos+2);
677
keyinfo->key_parts= (uint) strpos[4];
678
keyinfo->algorithm= (enum ha_key_alg) strpos[5];
679
keyinfo->block_size= uint2korr(strpos+6);
684
keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
685
keyinfo->key_length= (uint) uint2korr(strpos+1);
686
keyinfo->key_parts= (uint) strpos[3];
687
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
691
keyinfo->key_part= key_part;
692
keyinfo->rec_per_key= rec_per_key;
693
for (j=keyinfo->key_parts ; j-- ; key_part++)
696
key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
697
key_part->offset= (uint) uint2korr(strpos+2)-1;
698
key_part->key_type= (uint) uint2korr(strpos+5);
699
// key_part->field= (Field*) 0; // Will be fixed later
700
if (new_frm_ver >= 1)
702
key_part->key_part_flag= *(strpos+4);
703
key_part->length= (uint) uint2korr(strpos+7);
708
key_part->length= *(strpos+4);
709
key_part->key_part_flag=0;
710
if (key_part->length > 128)
712
key_part->length&=127; /* purecov: inspected */
713
key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
717
key_part->store_length=key_part->length;
720
keynames=(char*) key_part;
721
strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
723
//reading index comments
724
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
726
if (keyinfo->flags & HA_USES_COMMENT)
728
keyinfo->comment.length= uint2korr(strpos);
729
keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
730
keyinfo->comment.length);
731
strpos+= 2 + keyinfo->comment.length;
733
DBUG_ASSERT(test(keyinfo->flags & HA_USES_COMMENT) ==
734
(keyinfo->comment.length > 0));
737
share->reclength = uint2korr((head+16));
739
share->system= 1; /* one-record-database */
741
record_offset= (ulong) (uint2korr(head+6)+
742
((uint2korr(head+14) == 0xffff ?
743
uint4korr(head+47) : uint2korr(head+14))));
745
if ((n_length= uint4korr(head+55)))
747
/* Read extra data segment */
748
uchar *next_chunk, *buff_end;
749
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
750
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
752
if (my_pread(file, buff, n_length, record_offset + share->reclength,
757
share->connect_string.length= uint2korr(buff);
758
if (!(share->connect_string.str= strmake_root(&share->mem_root,
759
(char*) next_chunk + 2,
760
share->connect_string.
765
next_chunk+= share->connect_string.length + 2;
766
buff_end= buff + n_length;
767
if (next_chunk + 2 < buff_end)
769
uint str_db_type_length= uint2korr(next_chunk);
771
name.str= (char*) next_chunk + 2;
772
name.length= str_db_type_length;
774
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
775
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
777
if (legacy_db_type > DB_TYPE_UNKNOWN &&
778
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
779
legacy_db_type != ha_legacy_type(
780
plugin_data(tmp_plugin, handlerton *)))
782
/* bad file, legacy_db_type did not match the name */
783
my_free(buff, MYF(0));
787
tmp_plugin is locked with a local lock.
788
we unlock the old value of share->db_plugin before
789
replacing it with a globally locked version of tmp_plugin
791
plugin_unlock(NULL, share->db_plugin);
792
share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
793
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
794
str_db_type_length, next_chunk + 2,
795
ha_legacy_type(share->db_type())));
797
else if (!tmp_plugin)
799
/* purecov: begin inspected */
801
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
802
my_free(buff, MYF(0));
806
next_chunk+= str_db_type_length + 2;
808
#if MYSQL_VERSION_ID < 50200
809
if (share->mysql_version >= 50106 && share->mysql_version <= 50109)
812
Partition state array was here in version 5.1.6 to 5.1.9, this code
813
makes it possible to load a 5.1.6 table in later versions. Can most
814
likely be removed at some point in time. Will only be used for
815
upgrades within 5.1 series of versions. Upgrade to 5.2 can only be
816
done from newer 5.1 versions.
822
if (share->mysql_version >= 50110)
824
/* New auto_partitioned indicator introduced in 5.1.11 */
827
if (forminfo[46] == (uchar)255)
829
//reading long table comment
830
if (next_chunk + 2 > buff_end)
833
("long table comment is not defined in .frm"));
834
my_free(buff, MYF(0));
837
share->comment.length = uint2korr(next_chunk);
838
if (! (share->comment.str= strmake_root(&share->mem_root,
839
(char*)next_chunk + 2, share->comment.length)))
841
my_free(buff, MYF(0));
844
next_chunk+= 2 + share->comment.length;
846
DBUG_ASSERT (next_chunk <= buff_end);
847
if (share->mysql_version >= MYSQL_VERSION_TABLESPACE_IN_FRM_CGE)
850
New frm format in mysql_version 5.2.5 (originally in
851
mysql-5.1.22-ndb-6.2.5)
852
New column properties added:
853
COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
854
TABLESPACE name is now stored in frm
856
if (next_chunk >= buff_end)
858
if (share->mysql_version >= MYSQL_VERSION_TABLESPACE_IN_FRM)
860
DBUG_PRINT("error", ("Found no field extra info"));
863
DBUG_PRINT("info", ("Found no field extra info"));
867
DBUG_PRINT("info", ("Found field extra info"));
868
const uint format_section_header_size= 8;
869
uint format_section_len= uint2korr(next_chunk+0);
870
uint flags= uint4korr(next_chunk+2);
872
share->default_storage_media= (enum ha_storage_media) (flags & 0x7);
874
const char *tablespace= (const char*)next_chunk + format_section_header_size;
875
uint tablespace_len= strlen(tablespace);
876
if (tablespace_len != 0)
878
share->tablespace= (char *) alloc_root(&share->mem_root,
880
strxmov(share->tablespace, tablespace, NullS);
883
share->tablespace= NULL;
885
field_extra_info= next_chunk + format_section_header_size + tablespace_len + 1;
886
next_chunk+= format_section_len;
889
DBUG_ASSERT (next_chunk <= buff_end);
890
if (next_chunk > buff_end)
892
DBUG_PRINT("error", ("Buffer overflow in field extra info"));
896
share->key_block_size= uint2korr(head+62);
899
extra_rec_buf_length= uint2korr(head+59);
900
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
901
share->rec_buff_length= rec_buff_length;
902
if (!(record= (uchar *) alloc_root(&share->mem_root,
904
goto err; /* purecov: inspected */
905
share->default_values= record;
906
if (my_pread(file, record, (size_t) share->reclength,
907
record_offset, MYF(MY_NABP)))
908
goto err; /* purecov: inspected */
910
VOID(my_seek(file,pos+288,MY_SEEK_SET,MYF(0)));
912
share->fields= uint2korr(forminfo+258);
913
pos= uint2korr(forminfo+260); /* Length of all screens */
914
n_length= uint2korr(forminfo+268);
915
interval_count= uint2korr(forminfo+270);
916
interval_parts= uint2korr(forminfo+272);
917
int_length= uint2korr(forminfo+274);
918
share->null_fields= uint2korr(forminfo+282);
919
com_length= uint2korr(forminfo+284);
920
if (forminfo[46] != (uchar)255)
922
share->comment.length= (int) (forminfo[46]);
923
share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
924
share->comment.length);
927
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length));
929
if (!(field_ptr = (Field **)
930
alloc_root(&share->mem_root,
931
(uint) ((share->fields+1)*sizeof(Field*)+
932
interval_count*sizeof(TYPELIB)+
933
(share->fields+interval_parts+
934
keys+3)*sizeof(char *)+
935
(n_length+int_length+com_length)))))
936
goto err; /* purecov: inspected */
938
share->field= field_ptr;
939
read_length=(uint) (share->fields * field_pack_length +
940
pos+ (uint) (n_length+int_length+com_length));
941
if (read_string(file,(uchar**) &disk_buff,read_length))
942
goto err; /* purecov: inspected */
943
strpos= disk_buff+pos;
945
share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
946
interval_array= (const char **) (share->intervals+interval_count);
947
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
949
share->intervals= 0; // For better debugging
950
memcpy((char*) names, strpos+(share->fields*field_pack_length),
951
(uint) (n_length+int_length));
952
comment_pos= names+(n_length+int_length);
953
memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
955
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
956
if (share->fieldnames.count != share->fields)
958
fix_type_pointers(&interval_array, share->intervals, interval_count,
962
/* Set ENUM and SET lengths */
964
for (interval= share->intervals;
965
interval < share->intervals + interval_count;
968
uint count= (uint) (interval->count + 1) * sizeof(uint);
969
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
972
for (count= 0; count < interval->count; count++)
974
char *val= (char*) interval->type_names[count];
975
interval->type_lengths[count]= strlen(val);
977
interval->type_lengths[count]= 0;
982
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
984
/* Allocate handler */
985
if (!(handler_file= get_new_handler(share, thd->mem_root,
989
record= share->default_values-1; /* Fieldstart = 1 */
990
if (share->null_field_first)
992
null_flags= null_pos= (uchar*) record+1;
993
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
995
null_bytes below is only correct under the condition that
996
there are no bit fields. Correct values is set below after the
997
table struct is initialized
999
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
1001
#ifndef WE_WANT_TO_SUPPORT_VERY_OLD_FRM_FILES
1004
share->null_bytes= (share->null_fields+7)/8;
1005
null_flags= null_pos= (uchar*) (record + 1 +share->reclength -
1011
use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
1013
use_hash= !hash_init(&share->name_hash,
1014
system_charset_info,
1016
(hash_get_key) get_field_name,0,0);
1018
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
1020
uint pack_flag, interval_nr, unireg_type, recpos, field_length;
1021
enum_field_types field_type;
1022
enum ha_storage_media storage_type= HA_SM_DEFAULT;
1023
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
1024
CHARSET_INFO *charset=NULL;
1027
if (field_extra_info)
1029
char tmp= field_extra_info[i];
1030
storage_type= (enum ha_storage_media)(tmp & STORAGE_TYPE_MASK);
1031
column_format= (enum column_format_type)
1032
((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
1033
DBUG_PRINT("info", ("Field extra: storage %u format %u",
1034
storage_type, column_format));
1036
if (new_frm_ver >= 3)
1038
/* new frm file in 4.1 */
1039
field_length= uint2korr(strpos+3);
1040
recpos= uint3korr(strpos+5);
1041
pack_flag= uint2korr(strpos+8);
1042
unireg_type= (uint) strpos[10];
1043
interval_nr= (uint) strpos[12];
1044
uint comment_length=uint2korr(strpos+15);
1045
field_type=(enum_field_types) (uint) strpos[13];
1049
charset= &my_charset_bin;
1050
else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
1052
error= 5; // Unknown or unavailable charset
1053
errarg= (int) strpos[14];
1057
if (!comment_length)
1059
comment.str= (char*) "";
1064
comment.str= (char*) comment_pos;
1065
comment.length= comment_length;
1066
comment_pos+= comment_length;
1071
field_length= (uint) strpos[3];
1072
recpos= uint2korr(strpos+4),
1073
pack_flag= uint2korr(strpos+6);
1074
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
1075
unireg_type= (uint) strpos[8];
1076
interval_nr= (uint) strpos[10];
1079
field_type= (enum_field_types) f_packtype(pack_flag);
1080
if (f_is_binary(pack_flag))
1083
Try to choose the best 4.1 type:
1084
- for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
1085
try to find a binary collation for character set.
1086
- for other types (e.g. BLOB) just use my_charset_bin.
1088
if (!f_is_blob(pack_flag))
1090
// 3.23 or 4.0 string
1091
if (!(charset= get_charset_by_csname(share->table_charset->csname,
1092
MY_CS_BINSORT, MYF(0))))
1093
charset= &my_charset_bin;
1096
charset= &my_charset_bin;
1099
charset= share->table_charset;
1100
bzero((char*) &comment, sizeof(comment));
1103
if (interval_nr && charset->mbminlen > 1)
1105
/* Unescape UCS2 intervals from HEX notation */
1106
TYPELIB *interval= share->intervals + interval_nr - 1;
1107
unhex_type2(interval);
1110
#ifndef TO_BE_DELETED_ON_PRODUCTION
1111
if (field_type == MYSQL_TYPE_NEWDECIMAL && !share->mysql_version)
1114
Fix pack length of old decimal values from 5.0.3 -> 5.0.4
1115
The difference is that in the old version we stored precision
1116
in the .frm table while we now store the display_length
1118
uint decimals= f_decimals(pack_flag);
1119
field_length= my_decimal_precision_to_length(field_length,
1121
f_is_dec(pack_flag) == 0);
1122
sql_print_error("Found incompatible DECIMAL field '%s' in %s; "
1123
"Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
1124
share->fieldnames.type_names[i], share->table_name.str,
1125
share->table_name.str);
1126
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1127
ER_CRASHED_ON_USAGE,
1128
"Found incompatible DECIMAL field '%s' in %s; "
1129
"Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
1130
share->fieldnames.type_names[i],
1131
share->table_name.str,
1132
share->table_name.str);
1133
share->crashed= 1; // Marker for CHECK TABLE
1137
*field_ptr= reg_field=
1138
make_field(share, record+recpos,
1139
(uint32) field_length,
1140
null_pos, null_bit_pos,
1144
(Field::utype) MTYP_TYPENR(unireg_type),
1146
share->intervals+interval_nr-1 :
1148
share->fieldnames.type_names[i]);
1149
if (!reg_field) // Not supported field type
1152
goto err; /* purecov: inspected */
1155
reg_field->flags|= ((uint)storage_type << FIELD_STORAGE_FLAGS);
1156
reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
1157
reg_field->field_index= i;
1158
reg_field->comment=comment;
1159
if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
1161
if ((null_bit_pos+= field_length & 7) > 7)
1167
if (!(reg_field->flags & NOT_NULL_FLAG))
1169
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
1172
if (f_no_default(pack_flag))
1173
reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
1175
if (reg_field->unireg_check == Field::NEXT_NUMBER)
1176
share->found_next_number_field= field_ptr;
1177
if (share->timestamp_field == reg_field)
1178
share->timestamp_field_offset= i;
1181
(void) my_hash_insert(&share->name_hash,
1182
(uchar*) field_ptr); // never fail
1184
*field_ptr=0; // End marker
1186
/* Fix key->name and key_part->field */
1189
uint primary_key=(uint) (find_type((char*) primary_key_name,
1190
&share->keynames, 3) - 1);
1191
longlong ha_option= handler_file->ha_table_flags();
1192
keyinfo= share->key_info;
1193
key_part= keyinfo->key_part;
1195
for (uint key=0 ; key < share->keys ; key++,keyinfo++)
1197
uint usable_parts= 0;
1198
keyinfo->name=(char*) share->keynames.type_names[key];
1200
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1203
If the UNIQUE key doesn't have NULL columns and is not a part key
1204
declare this as a primary key.
1207
for (i=0 ; i < keyinfo->key_parts ;i++)
1209
uint fieldnr= key_part[i].fieldnr;
1211
share->field[fieldnr-1]->null_ptr ||
1212
share->field[fieldnr-1]->key_length() !=
1215
primary_key=MAX_KEY; // Can't be used
1221
for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1224
if (new_field_pack_flag <= 1)
1225
key_part->fieldnr= (uint16) find_field(share->field,
1226
share->default_values,
1227
(uint) key_part->offset,
1228
(uint) key_part->length);
1229
if (!key_part->fieldnr)
1231
error= 4; // Wrong file
1234
field= key_part->field= share->field[key_part->fieldnr-1];
1235
key_part->type= field->key_type();
1236
if (field->null_ptr)
1238
key_part->null_offset=(uint) ((uchar*) field->null_ptr -
1239
share->default_values);
1240
key_part->null_bit= field->null_bit;
1241
key_part->store_length+=HA_KEY_NULL_LENGTH;
1242
keyinfo->flags|=HA_NULL_PART_KEY;
1243
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1244
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1246
if (field->type() == MYSQL_TYPE_BLOB ||
1247
field->real_type() == MYSQL_TYPE_VARCHAR)
1249
if (field->type() == MYSQL_TYPE_BLOB)
1250
key_part->key_part_flag|= HA_BLOB_PART;
1252
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1253
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1254
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1255
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1257
Mark that there may be many matching values for one key
1258
combination ('a', 'a ', 'a '...)
1260
if (!(field->flags & BINARY_FLAG))
1261
keyinfo->flags|= HA_END_SPACE_KEY;
1263
if (field->type() == MYSQL_TYPE_BIT)
1264
key_part->key_part_flag|= HA_BIT_PART;
1266
if (i == 0 && key != primary_key)
1267
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1268
(keyinfo->key_parts == 1)) ?
1269
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1271
field->key_start.set_bit(key);
1272
if (field->key_length() == key_part->length &&
1273
!(field->flags & BLOB_FLAG))
1275
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1277
share->keys_for_keyread.set_bit(key);
1278
field->part_of_key.set_bit(key);
1279
field->part_of_key_not_clustered.set_bit(key);
1281
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1282
field->part_of_sortkey.set_bit(key);
1284
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1286
usable_parts++; // For FILESORT
1287
field->flags|= PART_KEY_FLAG;
1288
if (key == primary_key)
1290
field->flags|= PRI_KEY_FLAG;
1292
If this field is part of the primary key and all keys contains
1293
the primary key, then we can use any key to find this column
1295
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1297
field->part_of_key= share->keys_in_use;
1298
if (field->part_of_sortkey.is_set(key))
1299
field->part_of_sortkey= share->keys_in_use;
1302
if (field->key_length() != key_part->length)
1304
#ifndef TO_BE_DELETED_ON_PRODUCTION
1305
if (field->type() == MYSQL_TYPE_NEWDECIMAL)
1308
Fix a fatal error in decimal key handling that causes crashes
1309
on Innodb. We fix it by reducing the key length so that
1310
InnoDB never gets a too big key when searching.
1311
This allows the end user to do an ALTER TABLE to fix the
1314
keyinfo->key_length-= (key_part->length - field->key_length());
1315
key_part->store_length-= (uint16)(key_part->length -
1316
field->key_length());
1317
key_part->length= (uint16)field->key_length();
1318
sql_print_error("Found wrong key definition in %s; "
1319
"Please do \"ALTER TABLE '%s' FORCE \" to fix it!",
1320
share->table_name.str,
1321
share->table_name.str);
1322
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1323
ER_CRASHED_ON_USAGE,
1324
"Found wrong key definition in %s; "
1325
"Please do \"ALTER TABLE '%s' FORCE\" to fix "
1327
share->table_name.str,
1328
share->table_name.str);
1329
share->crashed= 1; // Marker for CHECK TABLE
1333
key_part->key_part_flag|= HA_PART_KEY_SEG;
1336
keyinfo->usable_key_parts= usable_parts; // Filesort
1338
set_if_bigger(share->max_key_length,keyinfo->key_length+
1339
keyinfo->key_parts);
1340
share->total_key_length+= keyinfo->key_length;
1342
MERGE tables do not have unique indexes. But every key could be
1343
an unique index on the underlying MyISAM table. (Bug #10400)
1345
if ((keyinfo->flags & HA_NOSAME) ||
1346
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1347
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1349
if (primary_key < MAX_KEY &&
1350
(share->keys_in_use.is_set(primary_key)))
1352
share->primary_key= primary_key;
1354
If we are using an integer as the primary key then allow the user to
1355
refer to it as '_rowid'
1357
if (share->key_info[primary_key].key_parts == 1)
1359
Field *field= share->key_info[primary_key].key_part[0].field;
1360
if (field && field->result_type() == INT_RESULT)
1362
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1363
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1369
share->primary_key = MAX_KEY; // we do not have a primary key
1372
share->primary_key= MAX_KEY;
1373
x_free((uchar*) disk_buff);
1375
if (new_field_pack_flag <= 1)
1377
/* Old file format with default as not null */
1378
uint null_length= (share->null_fields+7)/8;
1379
bfill(share->default_values + (null_flags - (uchar*) record),
1383
if (share->found_next_number_field)
1385
reg_field= *share->found_next_number_field;
1386
if ((int) (share->next_number_index= (uint)
1387
find_ref_key(share->key_info, share->keys,
1388
share->default_values, reg_field,
1389
&share->next_number_key_offset,
1390
&share->next_number_keypart)) < 0)
1392
/* Wrong field definition */
1397
reg_field->flags |= AUTO_INCREMENT_FLAG;
1400
if (share->blob_fields)
1405
/* Store offsets to blob fields to find them fast */
1406
if (!(share->blob_field= save=
1407
(uint*) alloc_root(&share->mem_root,
1408
(uint) (share->blob_fields* sizeof(uint)))))
1410
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1412
if ((*ptr)->flags & BLOB_FLAG)
1418
the correct null_bytes can now be set, since bitfields have been taken
1421
share->null_bytes= (null_pos - (uchar*) null_flags +
1422
(null_bit_pos + 7) / 8);
1423
share->last_null_bit_pos= null_bit_pos;
1425
share->db_low_byte_first= handler_file->low_byte_first();
1426
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1428
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1429
share->column_bitmap_size)))
1431
bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
1432
bitmap_set_all(&share->all_set);
1434
delete handler_file;
1437
(void) hash_check(&share->name_hash);
1440
my_free(buff, MYF(0));
1445
my_free(buff, MYF(0));
1446
share->error= error;
1447
share->open_errno= my_errno;
1448
share->errarg= errarg;
1449
x_free((uchar*) disk_buff);
1451
delete handler_file;
1452
hash_free(&share->name_hash);
1454
open_table_error(share, error, share->open_errno, errarg);
1456
} /* open_binary_frm */
1460
Open a table based on a TABLE_SHARE
1463
open_table_from_share()
1465
share Table definition
1466
alias Alias for table
1467
db_stat open flags (for example HA_OPEN_KEYFILE|
1468
HA_OPEN_RNDFILE..) can be 0 (example in
1470
prgflag READ_ALL etc..
1471
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1472
outparam result table
1473
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1474
if OTM_CREATE some errors are ignore
1475
if OTM_ALTER HA_OPEN is not called
1479
1 Error (see open_table_error)
1480
2 Error (see open_table_error)
1481
3 Wrong data in .frm file
1482
4 Error (see open_table_error)
1483
5 Error (see open_table_error: charset unavailable)
1484
7 Table definition has changed in engine
1487
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1488
uint db_stat, uint prgflag, uint ha_open_flags,
1489
TABLE *outparam, open_table_mode open_mode)
1492
uint records, i, bitmap_size;
1493
bool error_reported= FALSE;
1494
uchar *record, *bitmaps;
1496
DBUG_ENTER("open_table_from_share");
1497
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx, open mode:%s",
1499
share->table_name.str,
1501
(open_mode == OTM_OPEN)?"open":
1502
((open_mode == OTM_CREATE)?"create":"alter")));
1504
/* Parsing of partitioning information from .frm needs thd->lex set up. */
1505
DBUG_ASSERT(thd->lex->is_lex_started);
1508
bzero((char*) outparam, sizeof(*outparam));
1509
outparam->in_use= thd;
1511
outparam->db_stat= db_stat;
1512
outparam->write_row_record= NULL;
1514
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1516
if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
1518
outparam->quick_keys.init();
1519
outparam->covering_keys.init();
1520
outparam->keys_in_use_for_query.init();
1522
/* Allocate handler */
1524
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1526
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1532
DBUG_ASSERT(!db_stat);
1536
outparam->reginfo.lock_type= TL_UNLOCK;
1537
outparam->current_lock= F_UNLCK;
1539
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1541
if (prgflag & (READ_ALL+EXTRA_RECORD))
1544
if (!(record= (uchar*) alloc_root(&outparam->mem_root,
1545
share->rec_buff_length * records)))
1546
goto err; /* purecov: inspected */
1550
/* We are probably in hard repair, and the buffers should not be used */
1551
outparam->record[0]= outparam->record[1]= share->default_values;
1555
outparam->record[0]= record;
1557
outparam->record[1]= record+ share->rec_buff_length;
1559
outparam->record[1]= outparam->record[0]; // Safety
1564
We need this because when we read var-length rows, we are not updating
1565
bytes after end of varchar
1569
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1570
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1572
memcpy(outparam->record[1], share->default_values,
1573
share->rec_buff_length);
1577
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1578
(uint) ((share->fields+1)*
1580
goto err; /* purecov: inspected */
1582
outparam->field= field_ptr;
1584
record= (uchar*) outparam->record[0]-1; /* Fieldstart = 1 */
1585
if (share->null_field_first)
1586
outparam->null_flags= (uchar*) record+1;
1588
outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
1591
/* Setup copy of fields from share, but use the right alias and record */
1592
for (i=0 ; i < share->fields; i++, field_ptr++)
1594
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1597
(*field_ptr)= 0; // End marker
1599
if (share->found_next_number_field)
1600
outparam->found_next_number_field=
1601
outparam->field[(uint) (share->found_next_number_field - share->field)];
1602
if (share->timestamp_field)
1603
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1606
/* Fix key->name and key_part->field */
1607
if (share->key_parts)
1609
KEY *key_info, *key_info_end;
1610
KEY_PART_INFO *key_part;
1612
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1613
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1615
outparam->key_info= key_info;
1616
key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
1618
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1619
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1622
for (key_info_end= key_info + share->keys ;
1623
key_info < key_info_end ;
1626
KEY_PART_INFO *key_part_end;
1628
key_info->table= outparam;
1629
key_info->key_part= key_part;
1631
for (key_part_end= key_part+ key_info->key_parts ;
1632
key_part < key_part_end ;
1635
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1637
if (field->key_length() != key_part->length &&
1638
!(field->flags & BLOB_FLAG))
1641
We are using only a prefix of the column as a key:
1642
Create a new field for the key part that matches the index
1644
field= key_part->field=field->new_field(&outparam->mem_root,
1646
field->field_length= key_part->length;
1652
/* Allocate bitmaps */
1654
bitmap_size= share->column_bitmap_size;
1655
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1657
bitmap_init(&outparam->def_read_set,
1658
(my_bitmap_map*) bitmaps, share->fields, FALSE);
1659
bitmap_init(&outparam->def_write_set,
1660
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE);
1661
bitmap_init(&outparam->tmp_set,
1662
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
1663
outparam->default_column_bitmaps();
1665
/* The table struct is now initialized; Open the table */
1667
if (db_stat && open_mode != OTM_ALTER)
1670
if ((ha_err= (outparam->file->
1671
ha_open(outparam, share->normalized_path.str,
1672
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1673
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1674
((db_stat & HA_WAIT_IF_LOCKED) ||
1675
(specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
1676
HA_OPEN_WAIT_IF_LOCKED :
1677
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1678
HA_OPEN_ABORT_IF_LOCKED :
1679
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1681
/* Set a flag if the table is crashed and it can be auto. repaired */
1682
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1683
outparam->file->auto_repair() &&
1684
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1688
case HA_ERR_NO_SUCH_TABLE:
1690
The table did not exists in storage engine, use same error message
1691
as if the .frm file didn't exist
1698
Too many files opened, use same error message as if the .frm
1701
DBUG_PRINT("error", ("open file: %s failed, too many files opened (errno: %d)",
1702
share->normalized_path.str, ha_err));
1707
outparam->file->print_error(ha_err, MYF(0));
1708
error_reported= TRUE;
1709
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1713
goto err; /* purecov: inspected */
1717
#if defined(HAVE_purify) && !defined(DBUG_OFF)
1718
bzero((char*) bitmaps, bitmap_size*3);
1721
outparam->no_replicate= outparam->file &&
1722
test(outparam->file->ha_table_flags() &
1723
HA_HAS_OWN_BINLOGGING);
1724
thd->status_var.opened_tables++;
1729
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1730
open_table_error(share, error, my_errno, 0);
1731
delete outparam->file;
1732
outparam->file= 0; // For easier error checking
1733
outparam->db_stat=0;
1734
free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root
1735
my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
1736
DBUG_RETURN (error);
1741
Free information allocated by openfrm
1745
table TABLE object to free
1746
free_share Is 1 if we also want to free table_share
1749
int closefrm(register TABLE *table, bool free_share)
1752
DBUG_ENTER("closefrm");
1753
DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
1756
error=table->file->close();
1757
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
1761
for (Field **ptr=table->field ; *ptr ; ptr++)
1766
table->file= 0; /* For easier errorchecking */
1769
if (table->s->tmp_table == NO_TMP_TABLE)
1770
release_table_share(table->s, RELEASE_NORMAL);
1772
free_table_share(table->s);
1774
free_root(&table->mem_root, MYF(0));
1779
/* Deallocate temporary blob storage */
1781
void free_blobs(register TABLE *table)
1784
for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
1787
((Field_blob*) table->field[*ptr])->free();
1791
/* Find where a form starts */
1792
/* if formname is NullS then only formnames is read */
1794
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
1796
uint a_length,names,length;
1799
DBUG_ENTER("get_form_pos");
1801
names=uint2korr(head+8);
1802
a_length=(names+2)*sizeof(char *); /* Room for two extra */
1807
save_names->type_names=0; /* Clear if error */
1811
length=uint2korr(head+4);
1812
VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0)));
1813
if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
1815
my_read(file, buf+a_length, (size_t) (length+names*4),
1817
{ /* purecov: inspected */
1818
x_free((uchar*) buf); /* purecov: inspected */
1819
DBUG_RETURN(0L); /* purecov: inspected */
1821
pos= buf+a_length+length;
1822
ret_value=uint4korr(pos);
1827
my_free((uchar*) buf,MYF(0));
1830
bzero((char*) save_names,sizeof(save_names));
1834
str=(char *) (buf+a_length);
1835
fix_type_pointers((const char ***) &buf,save_names,1,&str);
1837
DBUG_RETURN(ret_value);
1842
Read string from a file with malloc
1845
We add an \0 at end of the read string to make reading of C strings easier
1848
int read_string(File file, uchar**to, size_t length)
1850
DBUG_ENTER("read_string");
1853
if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
1854
my_read(file, *to, length,MYF(MY_NABP)))
1856
x_free(*to); /* purecov: inspected */
1857
*to= 0; /* purecov: inspected */
1858
DBUG_RETURN(1); /* purecov: inspected */
1860
*((char*) *to+length)= '\0';
1865
/* Add a new form to a form file */
1867
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
1868
const char *newname)
1870
uint i,bufflength,maxlength,n_length,length,names;
1871
ulong endpos,newpos;
1872
uchar buff[IO_SIZE];
1874
DBUG_ENTER("make_new_entry");
1876
length=(uint) strlen(newname)+1;
1877
n_length=uint2korr(fileinfo+4);
1878
maxlength=uint2korr(fileinfo+6);
1879
names=uint2korr(fileinfo+8);
1880
newpos=uint4korr(fileinfo+10);
1882
if (64+length+n_length+(names+1)*4 > maxlength)
1885
int4store(fileinfo+10,newpos);
1886
endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1887
bufflength= (uint) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */
1889
while (endpos > maxlength)
1891
VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
1892
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1894
VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1896
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1898
endpos-=bufflength; bufflength=IO_SIZE;
1900
bzero(buff,IO_SIZE); /* Null new block */
1901
VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
1902
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1904
maxlength+=IO_SIZE; /* Fix old ref */
1905
int2store(fileinfo+6,maxlength);
1906
for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
1909
endpos=uint4korr(pos)+IO_SIZE;
1910
int4store(pos,endpos);
1917
VOID(strxmov((char*) buff,"/",newname,"/",NullS));
1920
VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1921
VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
1922
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1923
(names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
1924
names*4, MYF(MY_NABP+MY_WME))) ||
1925
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1926
DBUG_RETURN(0L); /* purecov: inspected */
1928
int2store(fileinfo+8,names+1);
1929
int2store(fileinfo+4,n_length+length);
1930
VOID(my_chsize(file, newpos, 0, MYF(MY_WME)));/* Append file with '\0' */
1931
DBUG_RETURN(newpos);
1932
} /* make_new_entry */
1935
/* error message when opening a form file */
1937
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1940
char buff[FN_REFLEN];
1941
myf errortype= ME_ERROR+ME_WAITTANG;
1942
DBUG_ENTER("open_table_error");
1947
if (db_errno == ENOENT)
1948
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1951
strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1952
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1953
errortype, buff, db_errno);
1959
const char *datext= "";
1961
if (share->db_type() != NULL)
1963
if ((file= get_new_handler(share, current_thd->mem_root,
1966
if (!(datext= *file->bas_ext()))
1970
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1971
ER_FILE_USED : ER_CANT_OPEN_FILE;
1972
strxmov(buff, share->normalized_path.str, datext, NullS);
1973
my_error(err_no,errortype, buff, db_errno);
1979
const char *csname= get_charset_name((uint) errarg);
1981
if (!csname || csname[0] =='?')
1983
my_snprintf(tmp, sizeof(tmp), "#%d", errarg);
1986
my_printf_error(ER_UNKNOWN_COLLATION,
1987
"Unknown collation '%s' in table '%-.64s' definition",
1988
MYF(0), csname, share->table_name.str);
1992
strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1993
my_printf_error(ER_NOT_FORM_FILE,
1994
"Table '%-.64s' was created with a different version "
1995
"of MySQL and cannot be read",
2000
default: /* Better wrong error than none */
2002
strxmov(buff, share->normalized_path.str, reg_ext, NullS);
2003
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
2007
} /* open_table_error */
2011
** fix a str_type to a array type
2012
** typeparts separated with some char. differents types are separated
2017
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
2020
char *type_name, *ptr;
2026
point_to_type->name=0;
2027
point_to_type->type_names= *array;
2029
if ((chr= *ptr)) /* Test if empty type */
2031
while ((type_name=strchr(ptr+1,chr)) != NullS)
2033
*((*array)++) = ptr+1;
2034
*type_name= '\0'; /* End string */
2037
ptr+=2; /* Skip end mark and last 0 */
2041
point_to_type->count= (uint) (*array - point_to_type->type_names);
2043
*((*array)++)= NullS; /* End of type */
2045
*names=ptr; /* Update end */
2047
} /* fix_type_pointers */
2050
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
2052
TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
2055
result->count=strings.elements;
2057
uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
2058
if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
2060
result->type_lengths= (uint*) (result->type_names + result->count + 1);
2061
List_iterator<String> it(strings);
2063
for (uint i=0; (tmp=it++) ; i++)
2065
result->type_names[i]= tmp->ptr();
2066
result->type_lengths[i]= tmp->length();
2068
result->type_names[result->count]= 0; // End marker
2069
result->type_lengths[result->count]= 0;
2075
Search after a field with given start & length
2076
If an exact field isn't found, return longest field with starts
2080
This is needed because in some .frm fields 'fieldnr' was saved wrong
2087
static uint find_field(Field **fields, uchar *record, uint start, uint length)
2093
for (field= fields, i=1 ; *field ; i++,field++)
2095
if ((*field)->offset(record) == start)
2097
if ((*field)->key_length() == length)
2099
if (!pos || fields[pos-1]->pack_length() <
2100
(*field)->pack_length())
2108
/* Check that the integer is in the internal */
2110
int set_zone(register int nr, int min_zone, int max_zone)
2119
/* Adjust number to next larger disk buffer */
2121
ulong next_io_size(register ulong pos)
2123
register ulong offset;
2124
if ((offset= pos & (IO_SIZE-1)))
2125
return pos-offset+IO_SIZE;
2127
} /* next_io_size */
2131
Store an SQL quoted string.
2136
pos string to be quoted
2140
This function works correctly with utf8 or single-byte charset strings.
2141
May fail with some multibyte charsets though.
2144
void append_unescaped(String *res, const char *pos, uint length)
2146
const char *end= pos+length;
2149
for (; pos != end ; pos++)
2151
#if defined(USE_MB) && MYSQL_VERSION_ID < 40100
2153
if (use_mb(default_charset_info) &&
2154
(mblen= my_ismbchar(default_charset_info, pos, end)))
2156
res->append(pos, mblen);
2163
case 0: /* Must be escaped for 'mysql' */
2167
case '\n': /* Must be escaped for logs */
2172
res->append('\\'); /* This gives better readability */
2176
res->append('\\'); /* Because of the sql syntax */
2180
res->append('\''); /* Because of the sql syntax */
2192
/* Create a .frm file */
2194
File create_frm(THD *thd, const char *name, const char *db,
2195
const char *table, uint reclength, uchar *fileinfo,
2196
HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
2200
uchar fill[IO_SIZE];
2201
int create_flags= O_RDWR | O_TRUNC;
2202
ulong key_comment_total_bytes= 0;
2205
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2206
create_flags|= O_EXCL | O_NOFOLLOW;
2208
/* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */
2209
if (create_info->max_rows > UINT_MAX32)
2210
create_info->max_rows= UINT_MAX32;
2211
if (create_info->min_rows > UINT_MAX32)
2212
create_info->min_rows= UINT_MAX32;
2214
if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
2216
uint key_length, tmp_key_length;
2218
bzero((char*) fileinfo,64);
2220
fileinfo[0]=(uchar) 254;
2222
fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
2224
fileinfo[3]= (uchar) ha_legacy_type(
2225
ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
2227
int2store(fileinfo+6,IO_SIZE); /* Next block starts here */
2228
for (i= 0; i < keys; i++)
2230
DBUG_ASSERT(test(key_info[i].flags & HA_USES_COMMENT) ==
2231
(key_info[i].comment.length > 0));
2232
if (key_info[i].flags & HA_USES_COMMENT)
2233
key_comment_total_bytes += 2 + key_info[i].comment.length;
2236
Keep in sync with pack_keys() in unireg.cc
2238
8 bytes for the key header
2239
9 bytes for each key-part (MAX_REF_PARTS)
2240
NAME_LEN bytes for the name
2241
1 byte for the NAMES_SEP_CHAR (before the name)
2243
6 bytes for the header
2244
1 byte for the NAMES_SEP_CHAR (after the last name)
2245
9 extra bytes (padding for safety? alignment?)
2248
key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
2249
key_comment_total_bytes);
2250
length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
2251
create_info->extra_size));
2252
int4store(fileinfo+10,length);
2253
tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
2254
int2store(fileinfo+14,tmp_key_length);
2255
int2store(fileinfo+16,reclength);
2256
int4store(fileinfo+18,create_info->max_rows);
2257
int4store(fileinfo+22,create_info->min_rows);
2258
/* fileinfo[26] is set in mysql_create_frm() */
2259
fileinfo[27]=2; // Use long pack-fields
2260
/* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
2261
create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
2262
int2store(fileinfo+30,create_info->table_options);
2263
fileinfo[32]=0; // No filename anymore
2264
fileinfo[33]=5; // Mark for 5.0 frm file
2265
int4store(fileinfo+34,create_info->avg_row_length);
2266
fileinfo[38]= (create_info->default_table_charset ?
2267
create_info->default_table_charset->number : 0);
2268
fileinfo[39]= (uchar) ((uint) create_info->transactional |
2269
((uint) create_info->page_checksum << 2));
2270
fileinfo[40]= (uchar) create_info->row_type;
2271
/* Next few bytes where for RAID support */
2278
int4store(fileinfo+47, key_length);
2279
tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store
2280
int4store(fileinfo+51, tmp);
2281
int4store(fileinfo+55, create_info->extra_size);
2283
59-60 is reserved for extra_rec_buf_length,
2284
61 for default_part_db_type
2286
int2store(fileinfo+62, create_info->key_block_size);
2287
bzero(fill,IO_SIZE);
2288
for (; length > IO_SIZE ; length-= IO_SIZE)
2290
if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
2292
VOID(my_close(file,MYF(0)));
2293
VOID(my_delete(name,MYF(0)));
2300
if (my_errno == ENOENT)
2301
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2303
my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2309
void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
2311
TABLE_SHARE *share= table->s;
2312
DBUG_ENTER("update_create_info_from_table");
2314
create_info->max_rows= share->max_rows;
2315
create_info->min_rows= share->min_rows;
2316
create_info->table_options= share->db_create_options;
2317
create_info->avg_row_length= share->avg_row_length;
2318
create_info->row_type= share->row_type;
2319
create_info->default_storage_media= share->default_storage_media;
2320
create_info->tablespace= share->tablespace;
2321
create_info->default_table_charset= share->table_charset;
2322
create_info->table_charset= 0;
2323
create_info->comment= share->comment;
2329
rename_file_ext(const char * from,const char * to,const char * ext)
2331
char from_b[FN_REFLEN],to_b[FN_REFLEN];
2332
VOID(strxmov(from_b,from,ext,NullS));
2333
VOID(strxmov(to_b,to,ext,NullS));
2334
return (my_rename(from_b,to_b,MYF(MY_WME)));
2339
Allocate string field in MEM_ROOT and return it as String
2343
mem MEM_ROOT for allocating
2344
field Field for retrieving of string
2352
bool get_field(MEM_ROOT *mem, Field *field, String *res)
2354
char buff[MAX_FIELD_WIDTH], *to;
2355
String str(buff,sizeof(buff),&my_charset_bin);
2358
field->val_str(&str);
2359
if (!(length= str.length()))
2364
if (!(to= strmake_root(mem, str.ptr(), length)))
2365
length= 0; // Safety fix
2366
res->set(to, length, ((Field_str*)field)->charset());
2372
Allocate string field in MEM_ROOT and return it as NULL-terminated string
2376
mem MEM_ROOT for allocating
2377
field Field for retrieving of string
2380
NullS string is empty
2381
# pointer to NULL-terminated string value of field
2384
char *get_field(MEM_ROOT *mem, Field *field)
2386
char buff[MAX_FIELD_WIDTH], *to;
2387
String str(buff,sizeof(buff),&my_charset_bin);
2390
field->val_str(&str);
2391
length= str.length();
2392
if (!length || !(to= (char*) alloc_root(mem,length+1)))
2394
memcpy(to,str.ptr(),(uint) length);
2401
given a buffer with a key value, and a map of keyparts
2402
that are present in this value, returns the length of the value
2404
uint calculate_key_len(TABLE *table, uint key, const uchar *buf,
2405
key_part_map keypart_map)
2407
/* works only with key prefixes */
2408
DBUG_ASSERT(((keypart_map + 1) & keypart_map) == 0);
2410
KEY *key_info= table->s->key_info+key;
2411
KEY_PART_INFO *key_part= key_info->key_part;
2412
KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
2415
while (key_part < end_key_part && keypart_map)
2417
length+= key_part->store_length;
2425
Check if database name is valid
2429
org_name Name of database and length
2432
If lower_case_table_names is set then database is converted to lower case
2439
bool check_db_name(LEX_STRING *org_name)
2441
char *name= org_name->str;
2442
uint name_length= org_name->length;
2444
if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
2447
if (lower_case_table_names && name != any_db)
2448
my_casedn_str(files_charset_info, name);
2450
return check_identifier_name(org_name);
2455
Allow anything as a table name, as long as it doesn't contain an
2461
bool check_table_name(const char *name, uint length)
2463
if (!length || length > NAME_LEN || name[length - 1] == ' ')
2466
ident.str= (char*) name;
2467
ident.length= length;
2468
return check_identifier_name(&ident);
2473
Eventually, a "length" argument should be added
2474
to this function, and the inner loop changed to
2475
check_identifier_name() call.
2477
bool check_column_name(const char *name)
2479
uint name_length= 0; // name length in symbols
2480
bool last_char_is_space= TRUE;
2484
#if defined(USE_MB) && defined(USE_MB_IDENT)
2485
last_char_is_space= my_isspace(system_charset_info, *name);
2486
if (use_mb(system_charset_info))
2488
int len=my_ismbchar(system_charset_info, name,
2489
name+system_charset_info->mbmaxlen);
2492
if (len > 3) /* Disallow non-BMP characters */
2500
last_char_is_space= *name==' ';
2503
NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
2504
It is defined as 0xFF, which is a not valid byte in utf8.
2505
This assert is to catch use of this byte if we decide to
2506
use non-utf8 as system_character_set.
2508
DBUG_ASSERT(*name != NAMES_SEP_CHAR);
2512
/* Error if empty or too long column name */
2513
return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2518
Checks whether a table is intact. Should be done *just* after the table has
2521
@param[in] table The table to check
2522
@param[in] table_f_count Expected number of columns in the table
2523
@param[in] table_def Expected structure of the table (column name
2527
@retval TRUE There was an error. An error message is output
2528
to the error log. We do not push an error
2529
message into the error stack because this
2530
function is currently only called at start up,
2531
and such errors never reach the user.
2535
table_check_intact(TABLE *table, const uint table_f_count,
2536
const TABLE_FIELD_W_TYPE *table_def)
2539
my_bool error= FALSE;
2540
my_bool fields_diff_count;
2541
DBUG_ENTER("table_check_intact");
2542
DBUG_PRINT("info",("table: %s expected_count: %d",
2543
table->alias, table_f_count));
2545
fields_diff_count= (table->s->fields != table_f_count);
2546
if (fields_diff_count)
2548
DBUG_PRINT("info", ("Column count has changed, checking the definition"));
2550
/* previous MySQL version */
2551
if (MYSQL_VERSION_ID > table->s->mysql_version)
2553
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2554
table->alias, table_f_count, table->s->fields,
2555
table->s->mysql_version, MYSQL_VERSION_ID);
2558
else if (MYSQL_VERSION_ID == table->s->mysql_version)
2560
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
2561
table_f_count, table->s->fields);
2565
Something has definitely changed, but we're running an older
2566
version of MySQL with new system tables.
2567
Let's check column definitions. If a column was added at
2568
the end of the table, then we don't care much since such change
2569
is backward compatible.
2572
char buffer[STRING_BUFFER_USUAL_SIZE];
2573
for (i=0 ; i < table_f_count; i++, table_def++)
2575
String sql_type(buffer, sizeof(buffer), system_charset_info);
2577
if (i < table->s->fields)
2579
Field *field= table->field[i];
2581
if (strncmp(field->field_name, table_def->name.str,
2582
table_def->name.length))
2585
Name changes are not fatal, we use ordinal numbers to access columns.
2586
Still this can be a sign of a tampered table, output an error
2589
sql_print_error("Incorrect definition of table %s.%s: "
2590
"expected column '%s' at position %d, found '%s'.",
2591
table->s->db.str, table->alias, table_def->name.str, i,
2594
field->sql_type(sql_type);
2596
Generally, if column types don't match, then something is
2599
However, we only compare column definitions up to the
2600
length of the original definition, since we consider the
2601
following definitions compatible:
2603
1. DATETIME and DATETIM
2604
2. INT(11) and INT(11
2605
3. SET('one', 'two') and SET('one', 'two', 'more')
2607
For SETs or ENUMs, if the same prefix is there it's OK to
2608
add more elements - they will get higher ordinal numbers and
2609
the new table definition is backward compatible with the
2612
if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2613
table_def->type.length - 1))
2615
sql_print_error("Incorrect definition of table %s.%s: "
2616
"expected column '%s' at position %d to have type "
2617
"%s, found type %s.", table->s->db.str, table->alias,
2618
table_def->name.str, i, table_def->type.str,
2619
sql_type.c_ptr_safe());
2622
else if (table_def->cset.str && !field->has_charset())
2624
sql_print_error("Incorrect definition of table %s.%s: "
2625
"expected the type of column '%s' at position %d "
2626
"to have character set '%s' but the type has no "
2627
"character set.", table->s->db.str, table->alias,
2628
table_def->name.str, i, table_def->cset.str);
2631
else if (table_def->cset.str &&
2632
strcmp(field->charset()->csname, table_def->cset.str))
2634
sql_print_error("Incorrect definition of table %s.%s: "
2635
"expected the type of column '%s' at position %d "
2636
"to have character set '%s' but found "
2637
"character set '%s'.", table->s->db.str, table->alias,
2638
table_def->name.str, i, table_def->cset.str,
2639
field->charset()->csname);
2645
sql_print_error("Incorrect definition of table %s.%s: "
2646
"expected column '%s' at position %d to have type %s "
2647
" but the column is not found.",
2648
table->s->db.str, table->alias,
2649
table_def->name.str, i, table_def->type.str);
2658
Create Item_field for each column in the table.
2661
st_table::fill_item_list()
2662
item_list a pointer to an empty list used to store items
2665
Create Item_field object for each column in the table and
2666
initialize it with the corresponding Field. New items are
2667
created in the current THD memory root.
2674
bool st_table::fill_item_list(List<Item> *item_list) const
2677
All Item_field's created using a direct pointer to a field
2678
are fixed in Item_field constructor.
2680
for (Field **ptr= field; *ptr; ptr++)
2682
Item_field *item= new Item_field(*ptr);
2683
if (!item || item_list->push_back(item))
2690
Reset an existing list of Item_field items to point to the
2691
Fields of this table.
2694
st_table::fill_item_list()
2695
item_list a non-empty list with Item_fields
2698
This is a counterpart of fill_item_list used to redirect
2699
Item_fields to the fields of a newly created table.
2700
The caller must ensure that number of items in the item_list
2701
is the same as the number of columns in the table.
2704
void st_table::reset_item_list(List<Item> *item_list) const
2706
List_iterator_fast<Item> it(*item_list);
2707
for (Field **ptr= field; *ptr; ptr++)
2709
Item_field *item_field= (Item_field*) it++;
2710
DBUG_ASSERT(item_field != 0);
2711
item_field->reset_field(*ptr);
2717
Merge ON expressions for a view
2722
table table for the VIEW
2723
is_cascaded TRUE <=> merge ON expressions from underlying views
2726
This function returns the result of ANDing the ON expressions
2727
of the given view and all underlying views. The ON expressions
2728
of the underlying views are added only if is_cascaded is TRUE.
2731
Pointer to the built expression if there is any.
2732
Otherwise and in the case of a failure NULL is returned.
2736
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
2738
DBUG_ENTER("merge_on_conds");
2741
DBUG_PRINT("info", ("alias: %s", table->alias));
2743
cond= table->on_expr->copy_andor_structure(thd);
2744
if (!table->nested_join)
2746
List_iterator<TABLE_LIST> li(table->nested_join->join_list);
2747
while (TABLE_LIST *tbl= li++)
2749
cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
2756
Find underlying base tables (TABLE_LIST) which represent given
2757
table_to_find (TABLE)
2760
TABLE_LIST::find_underlying_table()
2761
table_to_find table to find
2764
0 table is not found
2765
found table reference
2768
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
2770
/* is this real table and table which we are looking for? */
2771
if (table == table_to_find && merge_underlying_list == 0)
2774
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2777
if ((result= tbl->find_underlying_table(table_to_find)))
2784
cleunup items belonged to view fields translation table
2787
TABLE_LIST::cleanup_items()
2790
void TABLE_LIST::cleanup_items()
2792
if (!field_translation)
2795
for (Field_translator *transl= field_translation;
2796
transl < field_translation_end;
2798
transl->item->walk(&Item::cleanup_processor, 0, 0);
2803
Set insert_values buffer
2807
mem_root memory pool for allocating
2811
TRUE - out of memory
2814
bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
2818
if (!table->insert_values &&
2819
!(table->insert_values= (uchar *)alloc_root(mem_root,
2820
table->s->rec_buff_length)))
2829
Test if this is a leaf with respect to name resolution.
2832
TABLE_LIST::is_leaf_for_name_resolution()
2835
A table reference is a leaf with respect to name resolution if
2836
it is either a leaf node in a nested join tree (table, view,
2837
schema table, subquery), or an inner node that represents a
2838
NATURAL/USING join, or a nested join with materialized join
2842
TRUE if a leaf, FALSE otherwise.
2844
bool TABLE_LIST::is_leaf_for_name_resolution()
2846
return (is_natural_join || is_join_columns_complete || !nested_join);
2851
Retrieve the first (left-most) leaf in a nested join tree with
2852
respect to name resolution.
2855
TABLE_LIST::first_leaf_for_name_resolution()
2858
Given that 'this' is a nested table reference, recursively walk
2859
down the left-most children of 'this' until we reach a leaf
2860
table reference with respect to name resolution.
2863
The left-most child of a nested table reference is the last element
2864
in the list of children because the children are inserted in
2868
If 'this' is a nested table reference - the left-most child of
2869
the tree rooted in 'this',
2873
TABLE_LIST *TABLE_LIST::first_leaf_for_name_resolution()
2875
TABLE_LIST *cur_table_ref;
2876
NESTED_JOIN *cur_nested_join;
2878
if (is_leaf_for_name_resolution())
2880
DBUG_ASSERT(nested_join);
2882
for (cur_nested_join= nested_join;
2884
cur_nested_join= cur_table_ref->nested_join)
2886
List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
2887
cur_table_ref= it++;
2889
If the current nested join is a RIGHT JOIN, the operands in
2890
'join_list' are in reverse order, thus the first operand is
2891
already at the front of the list. Otherwise the first operand
2892
is in the end of the list of join operands.
2894
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2897
while ((next= it++))
2898
cur_table_ref= next;
2900
if (cur_table_ref->is_leaf_for_name_resolution())
2903
return cur_table_ref;
2908
Retrieve the last (right-most) leaf in a nested join tree with
2909
respect to name resolution.
2912
TABLE_LIST::last_leaf_for_name_resolution()
2915
Given that 'this' is a nested table reference, recursively walk
2916
down the right-most children of 'this' until we reach a leaf
2917
table reference with respect to name resolution.
2920
The right-most child of a nested table reference is the first
2921
element in the list of children because the children are inserted
2925
- If 'this' is a nested table reference - the right-most child of
2926
the tree rooted in 'this',
2930
TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
2932
TABLE_LIST *cur_table_ref= this;
2933
NESTED_JOIN *cur_nested_join;
2935
if (is_leaf_for_name_resolution())
2937
DBUG_ASSERT(nested_join);
2939
for (cur_nested_join= nested_join;
2941
cur_nested_join= cur_table_ref->nested_join)
2943
cur_table_ref= cur_nested_join->join_list.head();
2945
If the current nested is a RIGHT JOIN, the operands in
2946
'join_list' are in reverse order, thus the last operand is in the
2949
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2951
List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
2953
cur_table_ref= it++;
2954
while ((next= it++))
2955
cur_table_ref= next;
2957
if (cur_table_ref->is_leaf_for_name_resolution())
2960
return cur_table_ref;
2964
Natural_join_column::Natural_join_column(Field_translator *field_param,
2967
DBUG_ASSERT(tab->field_translation);
2968
view_field= field_param;
2975
Natural_join_column::Natural_join_column(Field *field_param,
2978
DBUG_ASSERT(tab->table == field_param->table);
2979
table_field= field_param;
2986
const char *Natural_join_column::name()
2990
DBUG_ASSERT(table_field == NULL);
2991
return view_field->name;
2994
return table_field->field_name;
2998
Item *Natural_join_column::create_item(THD *thd)
3002
DBUG_ASSERT(table_field == NULL);
3003
return create_view_field(thd, table_ref, &view_field->item,
3006
return new Item_field(thd, &thd->lex->current_select->context, table_field);
3010
Field *Natural_join_column::field()
3014
DBUG_ASSERT(table_field == NULL);
3021
const char *Natural_join_column::table_name()
3023
DBUG_ASSERT(table_ref);
3024
return table_ref->alias;
3028
const char *Natural_join_column::db_name()
3031
Test that TABLE_LIST::db is the same as st_table_share::db to
3032
ensure consistency. An exception are I_S schema tables, which
3033
are inconsistent in this respect.
3035
DBUG_ASSERT(!strcmp(table_ref->db,
3036
table_ref->table->s->db.str) ||
3037
(table_ref->schema_table &&
3038
table_ref->table->s->db.str[0] == 0));
3039
return table_ref->db;
3043
void Field_iterator_view::set(TABLE_LIST *table)
3045
DBUG_ASSERT(table->field_translation);
3047
ptr= table->field_translation;
3048
array_end= table->field_translation_end;
3052
const char *Field_iterator_table::name()
3054
return (*ptr)->field_name;
3058
Item *Field_iterator_table::create_item(THD *thd)
3060
SELECT_LEX *select= thd->lex->current_select;
3062
Item_field *item= new Item_field(thd, &select->context, *ptr);
3063
if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
3064
!thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
3066
select->non_agg_fields.push_back(item);
3067
item->marker= select->cur_pos_in_select_list;
3073
const char *Field_iterator_view::name()
3079
Item *Field_iterator_view::create_item(THD *thd)
3081
return create_view_field(thd, view, &ptr->item, ptr->name);
3084
Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
3087
DBUG_ENTER("create_view_field");
3088
if (view->schema_table_reformed)
3090
Item *field= *field_ref;
3093
Translation table items are always Item_fields and already fixed
3094
('mysql_schema_table' function). So we can return directly the
3095
field. This case happens only for 'show & where' commands.
3097
DBUG_ASSERT(field && field->fixed);
3105
void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
3107
DBUG_ASSERT(table_ref->join_columns);
3108
column_ref_it.init(*(table_ref->join_columns));
3109
cur_column_ref= column_ref_it++;
3113
void Field_iterator_natural_join::next()
3115
cur_column_ref= column_ref_it++;
3116
DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
3117
cur_column_ref->table_ref->table ==
3118
cur_column_ref->table_field->table);
3122
void Field_iterator_table_ref::set_field_iterator()
3124
DBUG_ENTER("Field_iterator_table_ref::set_field_iterator");
3126
If the table reference we are iterating over is a natural join, or it is
3127
an operand of a natural join, and TABLE_LIST::join_columns contains all
3128
the columns of the join operand, then we pick the columns from
3129
TABLE_LIST::join_columns, instead of the orginial container of the
3130
columns of the join operator.
3132
if (table_ref->is_join_columns_complete)
3134
/* Necesary, but insufficient conditions. */
3135
DBUG_ASSERT(table_ref->is_natural_join ||
3136
table_ref->nested_join ||
3137
table_ref->join_columns &&
3138
/* This is a merge view. */
3139
((table_ref->field_translation &&
3140
table_ref->join_columns->elements ==
3141
(ulong)(table_ref->field_translation_end -
3142
table_ref->field_translation)) ||
3143
/* This is stored table or a tmptable view. */
3144
(!table_ref->field_translation &&
3145
table_ref->join_columns->elements ==
3146
table_ref->table->s->fields)));
3147
field_it= &natural_join_it;
3148
DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join",
3151
/* This is a base table or stored view. */
3154
DBUG_ASSERT(table_ref->table);
3155
field_it= &table_field_it;
3156
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_table",
3159
field_it->set(table_ref);
3164
void Field_iterator_table_ref::set(TABLE_LIST *table)
3167
first_leaf= table->first_leaf_for_name_resolution();
3168
last_leaf= table->last_leaf_for_name_resolution();
3169
DBUG_ASSERT(first_leaf && last_leaf);
3170
table_ref= first_leaf;
3171
set_field_iterator();
3175
void Field_iterator_table_ref::next()
3177
/* Move to the next field in the current table reference. */
3180
If all fields of the current table reference are exhausted, move to
3181
the next leaf table reference.
3183
if (field_it->end_of_fields() && table_ref != last_leaf)
3185
table_ref= table_ref->next_name_resolution_table;
3186
DBUG_ASSERT(table_ref);
3187
set_field_iterator();
3192
const char *Field_iterator_table_ref::table_name()
3194
if (table_ref->is_natural_join)
3195
return natural_join_it.column_ref()->table_name();
3197
DBUG_ASSERT(!strcmp(table_ref->table_name,
3198
table_ref->table->s->table_name.str));
3199
return table_ref->table_name;
3203
const char *Field_iterator_table_ref::db_name()
3205
if (table_ref->is_natural_join)
3206
return natural_join_it.column_ref()->db_name();
3209
Test that TABLE_LIST::db is the same as st_table_share::db to
3210
ensure consistency. An exception are I_S schema tables, which
3211
are inconsistent in this respect.
3213
DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
3214
(table_ref->schema_table &&
3215
table_ref->table->s->db.str[0] == 0));
3217
return table_ref->db;
3222
Create new or return existing column reference to a column of a
3226
Field_iterator_table_ref::get_or_create_column_ref()
3227
parent_table_ref the parent table reference over which the
3228
iterator is iterating
3231
Create a new natural join column for the current field of the
3232
iterator if no such column was created, or return an already
3233
created natural join column. The former happens for base tables or
3234
views, and the latter for natural/using joins. If a new field is
3235
created, then the field is added to 'parent_table_ref' if it is
3236
given, or to the original table referene of the field if
3237
parent_table_ref == NULL.
3240
This method is designed so that when a Field_iterator_table_ref
3241
walks through the fields of a table reference, all its fields
3242
are created and stored as follows:
3243
- If the table reference being iterated is a stored table, view or
3244
natural/using join, store all natural join columns in a list
3245
attached to that table reference.
3246
- If the table reference being iterated is a nested join that is
3247
not natural/using join, then do not materialize its result
3248
fields. This is OK because for such table references
3249
Field_iterator_table_ref iterates over the fields of the nested
3250
table references (recursively). In this way we avoid the storage
3251
of unnecessay copies of result columns of nested joins.
3254
# Pointer to a column of a natural join (or its operand)
3255
NULL No memory to allocate the column
3258
Natural_join_column *
3259
Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
3261
Natural_join_column *nj_col;
3262
bool is_created= TRUE;
3264
TABLE_LIST *add_table_ref= parent_table_ref ?
3265
parent_table_ref : table_ref;
3267
if (field_it == &table_field_it)
3269
/* The field belongs to a stored table. */
3270
Field *tmp_field= table_field_it.field();
3271
nj_col= new Natural_join_column(tmp_field, table_ref);
3272
field_count= table_ref->table->s->fields;
3274
else if (field_it == &view_field_it)
3276
/* The field belongs to a merge view or information schema table. */
3277
Field_translator *translated_field= view_field_it.field_translator();
3278
nj_col= new Natural_join_column(translated_field, table_ref);
3279
field_count= table_ref->field_translation_end -
3280
table_ref->field_translation;
3285
The field belongs to a NATURAL join, therefore the column reference was
3286
already created via one of the two constructor calls above. In this case
3287
we just return the already created column reference.
3289
DBUG_ASSERT(table_ref->is_join_columns_complete);
3291
nj_col= natural_join_it.column_ref();
3292
DBUG_ASSERT(nj_col);
3294
DBUG_ASSERT(!nj_col->table_field ||
3295
nj_col->table_ref->table == nj_col->table_field->table);
3298
If the natural join column was just created add it to the list of
3299
natural join columns of either 'parent_table_ref' or to the table
3300
reference that directly contains the original field.
3304
/* Make sure not all columns were materialized. */
3305
DBUG_ASSERT(!add_table_ref->is_join_columns_complete);
3306
if (!add_table_ref->join_columns)
3308
/* Create a list of natural join columns on demand. */
3309
if (!(add_table_ref->join_columns= new List<Natural_join_column>))
3311
add_table_ref->is_join_columns_complete= FALSE;
3313
add_table_ref->join_columns->push_back(nj_col);
3315
If new fields are added to their original table reference, mark if
3316
all fields were added. We do it here as the caller has no easy way
3317
of knowing when to do it.
3318
If the fields are being added to parent_table_ref, then the caller
3319
must take care to mark when all fields are created/added.
3321
if (!parent_table_ref &&
3322
add_table_ref->join_columns->elements == field_count)
3323
add_table_ref->is_join_columns_complete= TRUE;
3331
Return an existing reference to a column of a natural/using join.
3334
Field_iterator_table_ref::get_natural_column_ref()
3337
The method should be called in contexts where it is expected that
3338
all natural join columns are already created, and that the column
3339
being retrieved is a Natural_join_column.
3342
# Pointer to a column of a natural join (or its operand)
3343
NULL No memory to allocate the column
3346
Natural_join_column *
3347
Field_iterator_table_ref::get_natural_column_ref()
3349
Natural_join_column *nj_col;
3351
DBUG_ASSERT(field_it == &natural_join_it);
3353
The field belongs to a NATURAL join, therefore the column reference was
3354
already created via one of the two constructor calls above. In this case
3355
we just return the already created column reference.
3357
nj_col= natural_join_it.column_ref();
3358
DBUG_ASSERT(nj_col &&
3359
(!nj_col->table_field ||
3360
nj_col->table_ref->table == nj_col->table_field->table));
3364
/*****************************************************************************
3365
Functions to handle column usage bitmaps (read_set, write_set etc...)
3366
*****************************************************************************/
3368
/* Reset all columns bitmaps */
3370
void st_table::clear_column_bitmaps()
3373
Reset column read/write usage. It's identical to:
3374
bitmap_clear_all(&table->def_read_set);
3375
bitmap_clear_all(&table->def_write_set);
3377
bzero((char*) def_read_set.bitmap, s->column_bitmap_size*2);
3378
column_bitmaps_set(&def_read_set, &def_write_set);
3383
Tell handler we are going to call position() and rnd_pos() later.
3386
This is needed for handlers that uses the primary key to find the
3387
row. In this case we have to extend the read bitmap with the primary
3391
void st_table::prepare_for_position()
3393
DBUG_ENTER("st_table::prepare_for_position");
3395
if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
3396
s->primary_key < MAX_KEY)
3398
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3400
file->column_bitmaps_signal();
3407
Mark that only fields from one key is used
3410
This changes the bitmap to use the tmp bitmap
3411
After this, you can't access any other columns in the table until
3412
bitmaps are reset, for example with st_table::clear_column_bitmaps()
3413
or st_table::restore_column_maps_after_mark_index()
3416
void st_table::mark_columns_used_by_index(uint index)
3418
MY_BITMAP *bitmap= &tmp_set;
3419
DBUG_ENTER("st_table::mark_columns_used_by_index");
3421
(void) file->extra(HA_EXTRA_KEYREAD);
3422
bitmap_clear_all(bitmap);
3423
mark_columns_used_by_index_no_reset(index, bitmap);
3424
column_bitmaps_set(bitmap, bitmap);
3430
Restore to use normal column maps after key read
3433
This reverse the change done by mark_columns_used_by_index
3436
For this to work, one must have the normal table maps in place
3437
when calling mark_columns_used_by_index
3440
void st_table::restore_column_maps_after_mark_index()
3442
DBUG_ENTER("st_table::restore_column_maps_after_mark_index");
3445
(void) file->extra(HA_EXTRA_NO_KEYREAD);
3446
default_column_bitmaps();
3447
file->column_bitmaps_signal();
3453
mark columns used by key, but don't reset other fields
3456
void st_table::mark_columns_used_by_index_no_reset(uint index,
3459
KEY_PART_INFO *key_part= key_info[index].key_part;
3460
KEY_PART_INFO *key_part_end= (key_part +
3461
key_info[index].key_parts);
3462
for (;key_part != key_part_end; key_part++)
3463
bitmap_set_bit(bitmap, key_part->fieldnr-1);
3468
Mark auto-increment fields as used fields in both read and write maps
3471
This is needed in insert & update as the auto-increment field is
3472
always set and sometimes read.
3475
void st_table::mark_auto_increment_column()
3477
DBUG_ASSERT(found_next_number_field);
3479
We must set bit in read set as update_auto_increment() is using the
3480
store() to check overflow of auto_increment values
3482
bitmap_set_bit(read_set, found_next_number_field->field_index);
3483
bitmap_set_bit(write_set, found_next_number_field->field_index);
3484
if (s->next_number_keypart)
3485
mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
3486
file->column_bitmaps_signal();
3491
Mark columns needed for doing an delete of a row
3494
Some table engines don't have a cursor on the retrieve rows
3495
so they need either to use the primary key or all columns to
3496
be able to delete a row.
3498
If the engine needs this, the function works as follows:
3499
- If primary key exits, mark the primary key columns to be read.
3500
- If not, mark all columns to be read
3502
If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
3503
mark all key columns as 'to-be-read'. This allows the engine to
3504
loop over the given record to find all keys and doesn't have to
3505
retrieve the row again.
3508
void st_table::mark_columns_needed_for_delete()
3510
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
3513
for (reg_field= field ; *reg_field ; reg_field++)
3515
if ((*reg_field)->flags & PART_KEY_FLAG)
3516
bitmap_set_bit(read_set, (*reg_field)->field_index);
3518
file->column_bitmaps_signal();
3520
if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
3521
(mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
3524
If the handler has no cursor capabilites, or we have row-based
3525
replication active for the current statement, we have to read
3526
either the primary key, the hidden primary key or all columns to
3527
be able to do an delete
3529
if (s->primary_key == MAX_KEY)
3530
file->use_hidden_primary_key();
3533
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3534
file->column_bitmaps_signal();
3541
Mark columns needed for doing an update of a row
3544
Some engines needs to have all columns in an update (to be able to
3545
build a complete row). If this is the case, we mark all not
3546
updated columns to be read.
3548
If this is no the case, we do like in the delete case and mark
3549
if neeed, either the primary key column or all columns to be read.
3550
(see mark_columns_needed_for_delete() for details)
3552
If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
3553
mark all USED key columns as 'to-be-read'. This allows the engine to
3554
loop over the given record to find all changed keys and doesn't have to
3555
retrieve the row again.
3558
void st_table::mark_columns_needed_for_update()
3560
DBUG_ENTER("mark_columns_needed_for_update");
3561
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
3563
/* Mark all used key columns for read */
3565
for (reg_field= field ; *reg_field ; reg_field++)
3567
/* Merge keys is all keys that had a column refered to in the query */
3568
if (merge_keys.is_overlapping((*reg_field)->part_of_key))
3569
bitmap_set_bit(read_set, (*reg_field)->field_index);
3571
file->column_bitmaps_signal();
3573
if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
3574
(mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
3577
If the handler has no cursor capabilites, or we have row-based
3578
logging active for the current statement, we have to read either
3579
the primary key, the hidden primary key or all columns to be
3580
able to do an update
3582
if (s->primary_key == MAX_KEY)
3583
file->use_hidden_primary_key();
3586
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3587
file->column_bitmaps_signal();
3595
Mark columns the handler needs for doing an insert
3597
For now, this is used to mark fields used by the trigger
3601
void st_table::mark_columns_needed_for_insert()
3603
if (found_next_number_field)
3604
mark_auto_increment_column();
3608
Cleanup this table for re-execution.
3611
TABLE_LIST::reinit_before_use()
3614
void TABLE_LIST::reinit_before_use(THD *thd)
3617
Reset old pointers to TABLEs: they are not valid since the tables
3618
were closed in the end of previous prepare or execute call.
3621
/* Reset is_schema_table_processed value(needed for I_S tables */
3622
schema_table_state= NOT_PROCESSED;
3624
TABLE_LIST *embedded; /* The table at the current level of nesting. */
3625
TABLE_LIST *parent_embedding= this; /* The parent nested table reference. */
3628
embedded= parent_embedding;
3629
if (embedded->prep_on_expr)
3630
embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
3631
parent_embedding= embedded->embedding;
3633
while (parent_embedding &&
3634
parent_embedding->nested_join->join_list.head() == embedded);
3638
Return subselect that contains the FROM list this table is taken from
3641
TABLE_LIST::containing_subselect()
3644
Subselect item for the subquery that contains the FROM list
3645
this table is taken from if there is any
3650
Item_subselect *TABLE_LIST::containing_subselect()
3652
return (select_lex ? select_lex->master_unit()->item : 0);
3656
Compiles the tagged hints list and fills up the bitmasks.
3659
process_index_hints()
3660
table the TABLE to operate on.
3663
The parser collects the index hints for each table in a "tagged list"
3664
(TABLE_LIST::index_hints). Using the information in this tagged list
3665
this function sets the members st_table::keys_in_use_for_query,
3666
st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
3667
st_table::force_index and st_table::covering_keys.
3669
Current implementation of the runtime does not allow mixing FORCE INDEX
3670
and USE INDEX, so this is checked here. Then the FORCE INDEX list
3671
(if non-empty) is appended to the USE INDEX list and a flag is set.
3673
Multiple hints of the same kind are processed so that each clause
3674
is applied to what is computed in the previous clause.
3676
USE INDEX (i1) USE INDEX (i2)
3679
and means "consider only i1 and i2".
3682
USE INDEX () USE INDEX (i1)
3685
and means "consider only the index i1"
3687
It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
3690
Different kind of hints (USE/FORCE/IGNORE) are processed in the following
3692
1. All indexes in USE (or FORCE) INDEX are added to the mask.
3695
e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
3696
as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
3698
As an optimization if there is a covering index, and we have
3699
IGNORE INDEX FOR GROUP/ORDER, and this index is used for the JOIN part,
3700
then we have to ignore the IGNORE INDEX FROM GROUP/ORDER.
3703
FALSE no errors found
3704
TRUE found and reported an error.
3706
bool TABLE_LIST::process_index_hints(TABLE *tbl)
3708
/* initialize the result variables */
3709
tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
3710
tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
3712
/* index hint list processing */
3715
key_map index_join[INDEX_HINT_FORCE + 1];
3716
key_map index_order[INDEX_HINT_FORCE + 1];
3717
key_map index_group[INDEX_HINT_FORCE + 1];
3720
bool have_empty_use_join= FALSE, have_empty_use_order= FALSE,
3721
have_empty_use_group= FALSE;
3722
List_iterator <Index_hint> iter(*index_hints);
3724
/* initialize temporary variables used to collect hints of each kind */
3725
for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
3727
index_join[type].clear_all();
3728
index_order[type].clear_all();
3729
index_group[type].clear_all();
3732
/* iterate over the hints list */
3733
while ((hint= iter++))
3737
/* process empty USE INDEX () */
3738
if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
3740
if (hint->clause & INDEX_HINT_MASK_JOIN)
3742
index_join[hint->type].clear_all();
3743
have_empty_use_join= TRUE;
3745
if (hint->clause & INDEX_HINT_MASK_ORDER)
3747
index_order[hint->type].clear_all();
3748
have_empty_use_order= TRUE;
3750
if (hint->clause & INDEX_HINT_MASK_GROUP)
3752
index_group[hint->type].clear_all();
3753
have_empty_use_group= TRUE;
3759
Check if an index with the given name exists and get his offset in
3760
the keys bitmask for the table
3762
if (tbl->s->keynames.type_names == 0 ||
3763
(pos= find_type(&tbl->s->keynames, hint->key_name.str,
3764
hint->key_name.length, 1)) <= 0)
3766
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
3772
/* add to the appropriate clause mask */
3773
if (hint->clause & INDEX_HINT_MASK_JOIN)
3774
index_join[hint->type].set_bit (pos);
3775
if (hint->clause & INDEX_HINT_MASK_ORDER)
3776
index_order[hint->type].set_bit (pos);
3777
if (hint->clause & INDEX_HINT_MASK_GROUP)
3778
index_group[hint->type].set_bit (pos);
3781
/* cannot mix USE INDEX and FORCE INDEX */
3782
if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3783
!index_order[INDEX_HINT_FORCE].is_clear_all() ||
3784
!index_group[INDEX_HINT_FORCE].is_clear_all()) &&
3785
(!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join ||
3786
!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
3787
!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
3789
my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
3790
index_hint_type_name[INDEX_HINT_FORCE]);
3794
/* process FORCE INDEX as USE INDEX with a flag */
3795
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3796
!index_order[INDEX_HINT_FORCE].is_clear_all() ||
3797
!index_group[INDEX_HINT_FORCE].is_clear_all())
3799
tbl->force_index= TRUE;
3800
index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
3801
index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
3802
index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
3805
/* apply USE INDEX */
3806
if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
3807
tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
3808
if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
3809
tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
3810
if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
3811
tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
3813
/* apply IGNORE INDEX */
3814
tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
3815
tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
3816
tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
3819
/* make sure covering_keys don't include indexes disabled with a hint */
3820
tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
3825
size_t max_row_length(TABLE *table, const uchar *data)
3827
TABLE_SHARE *table_s= table->s;
3828
size_t length= table_s->reclength + 2 * table_s->fields;
3829
uint *const beg= table_s->blob_field;
3830
uint *const end= beg + table_s->blob_fields;
3832
for (uint *ptr= beg ; ptr != end ; ++ptr)
3834
Field_blob* const blob= (Field_blob*) table->field[*ptr];
3835
length+= blob->get_length((const uchar*)
3836
(data + blob->offset(table->record[0]))) +
3843
Check type of .frm if we are not going to parse it
3854
frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
3857
uchar header[10]; /* This should be optimized */
3859
DBUG_ENTER("mysql_frm_type");
3861
*dbt= DB_TYPE_UNKNOWN;
3863
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
3864
DBUG_RETURN(FRMTYPE_ERROR);
3865
error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
3866
my_close(file, MYF(MY_WME));
3869
DBUG_RETURN(FRMTYPE_ERROR);
3872
This is just a check for DB_TYPE. We'll return default unknown type
3873
if the following test is true (arg #3). This should not have effect
3874
on return value from this function (default FRMTYPE_TABLE)
3876
if (header[0] != (uchar) 254 || header[1] != 1 ||
3877
(header[2] != FRM_VER && header[2] != FRM_VER+1 &&
3878
(header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
3879
DBUG_RETURN(FRMTYPE_TABLE);
3881
*dbt= (enum legacy_db_type) (uint) *(header + 3);
3882
DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
3886
/*****************************************************************************
3887
** Instansiate templates
3888
*****************************************************************************/
3890
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3891
template class List<String>;
3892
template class List_iterator<String>;