17
17
/* Some general useful functions */
28
#include <drizzled/error.h>
29
#include <drizzled/gettext.h>
31
#include "drizzled/plugin/transactional_storage_engine.h"
32
#include "drizzled/plugin/authorization.h"
33
#include <drizzled/nested_join.h>
34
#include <drizzled/sql_parse.h>
35
#include <drizzled/item/sum.h>
36
#include <drizzled/table_list.h>
37
#include <drizzled/session.h>
38
#include <drizzled/sql_base.h>
39
#include <drizzled/sql_select.h>
40
#include <drizzled/field/blob.h>
41
#include <drizzled/field/varstring.h>
42
#include <drizzled/field/double.h>
43
#include <drizzled/unireg.h>
44
#include <drizzled/message/table.pb.h>
45
#include "drizzled/sql_table.h"
46
#include "drizzled/charset.h"
47
#include "drizzled/internal/m_string.h"
48
#include "plugin/myisam/myisam.h"
50
#include <drizzled/item/string.h>
51
#include <drizzled/item/int.h>
52
#include <drizzled/item/decimal.h>
53
#include <drizzled/item/float.h>
54
#include <drizzled/item/null.h>
55
#include <drizzled/temporal.h>
57
#include "drizzled/table_share_instance.h"
59
#include "drizzled/table_proto.h"
66
extern pid_t current_pid;
67
extern plugin::StorageEngine *heap_engine;
68
extern plugin::StorageEngine *myisam_engine;
70
/* Functions defined in this cursor */
72
void open_table_error(TableShare *share, int error, int db_errno,
19
#include <drizzled/server_includes.h>
20
#include <drizzled/drizzled_error_messages.h>
22
#include "tmp_table.h"
23
#include "sj_tmp_table.h"
25
/* INFORMATION_SCHEMA name */
26
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
28
/* Functions defined in this file */
30
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
73
31
myf errortype, int errarg);
32
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
unsigned char *head, File file);
34
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
35
uint32_t types, char **names);
36
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length);
75
38
/*************************************************************************/
77
// @note this should all be the destructor
78
int Table::delete_table(bool free_share)
83
error= cursor->close();
88
for (Field **ptr=field ; *ptr ; ptr++)
40
/* Get column name from column hash */
42
static unsigned char *get_field_name(Field **buff, size_t *length,
43
bool not_used __attribute__((unused)))
45
*length= (uint) strlen((*buff)->field_name);
46
return (unsigned char*) (*buff)->field_name;
51
Returns pointer to '.frm' extension of the file name.
58
Checks file name part starting with the rightmost '.' character,
59
and returns it if it is equal to '.frm'.
62
It is a good idea to get rid of this function modifying the code
63
to garantee that the functions presently calling fn_rext() always
64
get arguments in the same format: either with '.frm' or without '.frm'.
67
Pointer to the '.frm' extension. If there is no extension,
68
or extension is not '.frm', pointer at the end of file name.
71
char *fn_rext(char *name)
73
char *res= strrchr(name, '.');
74
if (res && !strcmp(res, reg_ext))
76
return name + strlen(name);
79
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
84
if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
85
(my_strcasecmp(system_charset_info,
86
INFORMATION_SCHEMA_NAME.str,
89
return TABLE_CATEGORY_INFORMATION;
92
return TABLE_CATEGORY_USER;
97
Allocate a setup TABLE_SHARE structure
101
TableList Take database and table name from there
102
key Table cache key (db \0 table_name \0...)
103
key_length Length of key
106
0 Error (out of memory)
110
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
115
char *key_buff, *path_buff;
116
char path[FN_REFLEN];
117
uint32_t path_length;
119
path_length= build_table_filename(path, sizeof(path) - 1,
121
table_list->table_name, "", 0);
122
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
123
if (multi_alloc_root(&mem_root,
124
&share, sizeof(*share),
125
&key_buff, key_length,
126
&path_buff, path_length + 1,
129
memset(share, 0, sizeof(*share));
131
share->set_table_cache_key(key_buff, key, key_length);
133
share->path.str= path_buff;
134
share->path.length= path_length;
135
my_stpcpy(share->path.str, path);
136
share->normalized_path.str= share->path.str;
137
share->normalized_path.length= path_length;
139
share->version= refresh_version;
142
This constant is used to mark that no table map version has been
143
assigned. No arithmetic is done on the value: it will be
144
overwritten with a value taken from DRIZZLE_BIN_LOG.
146
share->table_map_version= UINT64_MAX;
149
Since alloc_table_share() can be called without any locking (for
150
example, ha_create_table... functions), we do not assign a table
151
map id here. Instead we assign a value that is not used
152
elsewhere, and then assign a table map id inside open_table()
153
under the protection of the LOCK_open mutex.
155
share->table_map_id= UINT32_MAX;
156
share->cached_row_logging_check= -1;
158
memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
159
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
160
pthread_cond_init(&share->cond, NULL);
167
Initialize share for temporary tables
170
init_tmp_table_share()
173
key Table_cache_key, as generated from create_table_def_key.
174
must start with db name.
175
key_length Length of key
176
table_name Table name
177
path Path to file (possible in lower case) without .frm
180
This is different from alloc_table_share() because temporary tables
181
don't have to be shared between threads or put into the table def
182
cache, so we can do some things notable simpler and faster
184
If table is not put in thd->temporary_tables (happens only when
185
one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
use key_length= 0 as neither table_cache_key or key_length will be used).
189
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
190
uint32_t key_length, const char *table_name,
194
memset(share, 0, sizeof(*share));
195
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
196
share->table_category= TABLE_CATEGORY_TEMPORARY;
197
share->tmp_table= INTERNAL_TMP_TABLE;
198
share->db.str= (char*) key;
199
share->db.length= strlen(key);
200
share->table_cache_key.str= (char*) key;
201
share->table_cache_key.length= key_length;
202
share->table_name.str= (char*) table_name;
203
share->table_name.length= strlen(table_name);
204
share->path.str= (char*) path;
205
share->normalized_path.str= (char*) path;
206
share->path.length= share->normalized_path.length= strlen(path);
207
share->frm_version= FRM_VER_TRUE_VARCHAR;
209
Temporary tables are not replicated, but we set up these fields
210
anyway to be able to catch errors.
212
share->table_map_version= ~(uint64_t)0;
213
share->cached_row_logging_check= -1;
216
table_map_id is also used for MERGE tables to suppress repeated
217
compatibility checks.
219
share->table_map_id= (ulong) thd->query_id;
226
Free table share and memory used by it
233
share->mutex must be locked when we come here if it's not a temp table
236
void free_table_share(TABLE_SHARE *share)
239
assert(share->ref_count == 0);
242
If someone is waiting for this to be deleted, inform it about this.
243
Don't do a delete until we know that no one is refering to this anymore.
245
if (share->tmp_table == NO_TMP_TABLE)
247
/* share->mutex is locked in release_table_share() */
248
while (share->waiting_on_cond)
250
pthread_cond_broadcast(&share->cond);
251
pthread_cond_wait(&share->cond, &share->mutex);
253
/* No thread refers to this anymore */
254
pthread_mutex_unlock(&share->mutex);
255
pthread_mutex_destroy(&share->mutex);
256
pthread_cond_destroy(&share->cond);
258
hash_free(&share->name_hash);
260
plugin_unlock(NULL, share->db_plugin);
261
share->db_plugin= NULL;
263
/* We must copy mem_root from share because share is allocated through it */
264
memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
265
free_root(&mem_root, MYF(0)); // Free's share
270
Read table definition from a binary / text based .frm file
275
share Fill this with table definition
276
db_flags Bit mask of the following flags: OPEN_VIEW
279
This function is called when the table definition is not cached in
281
The data is returned in 'share', which is alloced by
282
alloc_table_share().. The code assumes that share is initialized.
286
1 Error (see open_table_error)
287
2 Error (see open_table_error)
288
3 Wrong data in .frm file
289
4 Error (see open_table_error)
290
5 Error (see open_table_error: charset unavailable)
291
6 Unknown .frm version
294
int open_table_def(THD *thd, TABLE_SHARE *share, uint32_t db_flags __attribute__((unused)))
296
int error, table_type;
299
unsigned char head[64], *disk_buff;
300
char path[FN_REFLEN];
301
MEM_ROOT **root_ptr, *old_root;
307
strxmov(path, share->normalized_path.str, reg_ext, NULL);
308
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
311
We don't try to open 5.0 unencoded name, if
312
- non-encoded name contains '@' signs,
313
because '@' can be misinterpreted.
314
It is not clear if '@' is escape character in 5.1,
315
or a normal character in 5.0.
317
- non-encoded db or table name contain "#mysql50#" prefix.
318
This kind of tables must have been opened only by the
321
if (strchr(share->table_name.str, '@') ||
322
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
323
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
324
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
325
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
328
/* Try unencoded 5.0 name */
330
strxnmov(path, sizeof(path)-1,
331
mysql_data_home, "/", share->db.str, "/",
332
share->table_name.str, reg_ext, NULL);
333
length= unpack_filename(path, path) - reg_ext_length;
335
The following is a safety test and should never fail
336
as the old file name should never be longer than the new one.
338
assert(length <= share->normalized_path.length);
340
If the old and the new names have the same length,
341
then table name does not have tricky characters,
342
so no need to check the old file name.
344
if (length == share->normalized_path.length ||
345
((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
348
/* Unencoded 5.0 table name found */
349
path[length]= '\0'; // Remove .frm extension
350
my_stpcpy(share->normalized_path.str, path);
351
share->normalized_path.length= length;
355
if (my_read(file, head, 64, MYF(MY_NABP)))
358
if (head[0] == (unsigned char) 254 && head[1] == 1)
360
if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
361
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
367
error= 6; // Unkown .frm version
374
/* No handling of text based files yet */
377
root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
379
*root_ptr= &share->mem_root;
380
error= open_binary_frm(thd, share, head, file);
387
share->table_category= get_table_category(& share->db, & share->table_name);
390
thd->status_var.opened_shares++;
393
my_close(file, MYF(MY_WME));
396
if (error && !error_given)
399
open_table_error(share, error, (share->open_errno= my_errno), 0);
407
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
410
static int open_binary_frm(THD *thd, TABLE_SHARE *share, unsigned char *head,
413
int error, errarg= 0;
414
uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
415
uint32_t interval_count, interval_parts, read_length, int_length;
416
uint32_t db_create_options, keys, key_parts, n_length;
417
uint32_t key_info_length, com_length, null_bit_pos=0;
418
uint32_t extra_rec_buf_length;
421
unsigned char forminfo[288];
422
char *keynames, *names, *comment_pos;
423
unsigned char *record;
424
unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
425
ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
handler *handler_file= 0;
428
KEY_PART_INFO *key_part;
429
Field **field_ptr, *reg_field;
430
const char **interval_array;
431
enum legacy_db_type legacy_db_type;
432
my_bitmap_map *bitmaps;
433
unsigned char *buff= 0;
434
unsigned char *field_extra_info= 0;
436
new_field_pack_flag= head[27];
437
new_frm_ver= (head[2] - FRM_VER);
438
field_pack_length= new_frm_ver < 2 ? 11 : 17;
442
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
443
goto err; /* purecov: inspected */
444
my_seek(file,pos,MY_SEEK_SET,MYF(0));
445
if (my_read(file,forminfo,288,MYF(MY_NABP)))
448
share->frm_version= head[2];
450
Check if .frm file created by MySQL 5.0. In this case we want to
451
display CHAR fields as CHAR and not as VARCHAR.
452
We do it this way as we want to keep the old frm version to enable
453
MySQL 4.1 to read these files.
455
if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
456
share->frm_version= FRM_VER_TRUE_VARCHAR;
458
legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
459
assert(share->db_plugin == NULL);
461
if the storage engine is dynamic, no point in resolving it by its
462
dynamically allocated legacy_db_type. We will resolve it later by name.
464
if (legacy_db_type > DB_TYPE_UNKNOWN &&
465
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
466
share->db_plugin= ha_lock_engine(NULL,
467
ha_checktype(thd, legacy_db_type, 0, 0));
468
share->db_create_options= db_create_options= uint2korr(head+30);
469
share->db_options_in_use= share->db_create_options;
470
share->mysql_version= uint4korr(head+51);
471
share->null_field_first= 0;
472
if (!head[32]) // New frm file in 3.23
474
share->avg_row_length= uint4korr(head+34);
475
share->transactional= (ha_choice) (head[39] & 3);
476
share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
477
share->row_type= (row_type) head[40];
478
share->block_size= uint4korr(head+43);
479
share->table_charset= get_charset((uint) head[38],MYF(0));
480
share->null_field_first= 1;
482
if (!share->table_charset)
484
/* unknown charset in head[38] or pre-3.23 frm */
485
if (use_mb(default_charset_info))
487
/* Warn that we may be changing the size of character columns */
488
sql_print_warning(_("'%s' had no or invalid character set, "
489
"and default character set is multi-byte, "
490
"so character column sizes may have changed"),
493
share->table_charset= default_charset_info;
495
share->db_record_offset= 1;
496
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
497
share->blob_ptr_size= portable_sizeof_char_ptr;
498
/* Set temporarily a good value for db_low_byte_first */
499
share->db_low_byte_first= true;
501
share->max_rows= uint4korr(head+18);
502
share->min_rows= uint4korr(head+22);
504
/* Read keyinformation */
505
key_info_length= (uint) uint2korr(head+28);
506
my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
507
if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
508
goto err; /* purecov: inspected */
509
if (disk_buff[0] & 0x80)
511
share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
512
share->key_parts= key_parts= uint2korr(disk_buff+2);
516
share->keys= keys= disk_buff[0];
517
share->key_parts= key_parts= disk_buff[1];
519
share->keys_for_keyread.init(0);
520
share->keys_in_use.init(keys);
522
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
523
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
524
n_length + uint2korr(disk_buff+4))))
525
goto err; /* purecov: inspected */
526
memset(keyinfo, 0, n_length);
527
share->key_info= keyinfo;
528
key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
531
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
532
sizeof(ulong*)*key_parts)))
535
for (i=0 ; i < keys ; i++, keyinfo++)
537
keyinfo->table= 0; // Updated in open_frm
538
if (new_frm_ver >= 3)
540
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
541
keyinfo->key_length= (uint) uint2korr(strpos+2);
542
keyinfo->key_parts= (uint) strpos[4];
543
keyinfo->algorithm= (enum ha_key_alg) strpos[5];
544
keyinfo->block_size= uint2korr(strpos+6);
548
keyinfo->key_part= key_part;
549
keyinfo->rec_per_key= rec_per_key;
550
for (j=keyinfo->key_parts ; j-- ; key_part++)
553
key_part->fieldnr= (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
554
key_part->offset= (uint) uint2korr(strpos+2)-1;
555
key_part->key_type= (uint) uint2korr(strpos+5);
556
// key_part->field= (Field*) 0; // Will be fixed later
557
if (new_frm_ver >= 1)
559
key_part->key_part_flag= *(strpos+4);
560
key_part->length= (uint) uint2korr(strpos+7);
565
key_part->length= *(strpos+4);
566
key_part->key_part_flag=0;
567
if (key_part->length > 128)
569
key_part->length&=127; /* purecov: inspected */
570
key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
574
key_part->store_length=key_part->length;
577
keynames=(char*) key_part;
578
strpos+= (my_stpcpy(keynames, (char *) strpos) - keynames)+1;
580
//reading index comments
581
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
583
if (keyinfo->flags & HA_USES_COMMENT)
585
keyinfo->comment.length= uint2korr(strpos);
586
keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
587
keyinfo->comment.length);
588
strpos+= 2 + keyinfo->comment.length;
590
assert(test(keyinfo->flags & HA_USES_COMMENT) ==
591
(keyinfo->comment.length > 0));
594
share->reclength = uint2korr((head+16));
596
record_offset= (ulong) (uint2korr(head+6)+
597
((uint2korr(head+14) == 0xffff ?
598
uint4korr(head+47) : uint2korr(head+14))));
600
if ((n_length= uint4korr(head+55)))
602
/* Read extra data segment */
603
unsigned char *next_chunk, *buff_end;
604
if (!(next_chunk= buff= (unsigned char*) my_malloc(n_length, MYF(MY_WME))))
606
if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
610
share->connect_string.length= uint2korr(buff);
611
if (!(share->connect_string.str= strmake_root(&share->mem_root,
612
(char*) next_chunk + 2,
613
share->connect_string.
618
next_chunk+= share->connect_string.length + 2;
619
buff_end= buff + n_length;
620
if (next_chunk + 2 < buff_end)
622
uint32_t str_db_type_length= uint2korr(next_chunk);
624
name.str= (char*) next_chunk + 2;
625
name.length= str_db_type_length;
627
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
628
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
630
if (legacy_db_type > DB_TYPE_UNKNOWN &&
631
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
632
legacy_db_type != ha_legacy_type(
633
plugin_data(tmp_plugin, handlerton *)))
635
/* bad file, legacy_db_type did not match the name */
640
tmp_plugin is locked with a local lock.
641
we unlock the old value of share->db_plugin before
642
replacing it with a globally locked version of tmp_plugin
644
plugin_unlock(NULL, share->db_plugin);
645
share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
647
else if (!tmp_plugin)
649
/* purecov: begin inspected */
651
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
656
next_chunk+= str_db_type_length + 2;
658
if (share->mysql_version >= 50110)
660
/* New auto_partitioned indicator introduced in 5.1.11 */
663
if (forminfo[46] == (unsigned char)255)
665
//reading long table comment
666
if (next_chunk + 2 > buff_end)
671
share->comment.length = uint2korr(next_chunk);
672
if (! (share->comment.str= strmake_root(&share->mem_root,
673
(char*)next_chunk + 2, share->comment.length)))
678
next_chunk+= 2 + share->comment.length;
680
assert(next_chunk <= buff_end);
681
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
684
New frm format in mysql_version 5.2.5 (originally in
685
mysql-5.1.22-ndb-6.2.5)
686
New column properties added:
687
COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
688
TABLESPACE name is now stored in frm
690
if (next_chunk >= buff_end)
692
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
699
const uint32_t format_section_header_size= 8;
700
uint32_t format_section_len= uint2korr(next_chunk+0);
702
field_extra_info= next_chunk + format_section_header_size + 1;
703
next_chunk+= format_section_len;
706
assert (next_chunk <= buff_end);
707
if (next_chunk > buff_end)
712
share->key_block_size= uint2korr(head+62);
715
extra_rec_buf_length= uint2korr(head+59);
716
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
717
share->rec_buff_length= rec_buff_length;
718
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
720
goto err; /* purecov: inspected */
721
share->default_values= record;
722
if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
723
goto err; /* purecov: inspected */
725
my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
727
share->fields= uint2korr(forminfo+258);
728
pos= uint2korr(forminfo+260); /* Length of all screens */
729
n_length= uint2korr(forminfo+268);
730
interval_count= uint2korr(forminfo+270);
731
interval_parts= uint2korr(forminfo+272);
732
int_length= uint2korr(forminfo+274);
733
share->null_fields= uint2korr(forminfo+282);
734
com_length= uint2korr(forminfo+284);
735
if (forminfo[46] != (unsigned char)255)
737
share->comment.length= (int) (forminfo[46]);
738
share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
share->comment.length);
743
if (!(field_ptr = (Field **)
744
alloc_root(&share->mem_root,
745
(uint) ((share->fields+1)*sizeof(Field*)+
746
interval_count*sizeof(TYPELIB)+
747
(share->fields+interval_parts+
748
keys+3)*sizeof(char *)+
749
(n_length+int_length+com_length)))))
750
goto err; /* purecov: inspected */
752
share->field= field_ptr;
753
read_length=(uint) (share->fields * field_pack_length +
754
pos+ (uint) (n_length+int_length+com_length));
755
if (read_string(file,(unsigned char**) &disk_buff,read_length))
756
goto err; /* purecov: inspected */
757
strpos= disk_buff+pos;
759
share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
760
interval_array= (const char **) (share->intervals+interval_count);
761
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
763
share->intervals= 0; // For better debugging
764
memcpy(names, strpos+(share->fields*field_pack_length),
765
(uint) (n_length+int_length));
766
comment_pos= names+(n_length+int_length);
767
memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
769
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
770
if (share->fieldnames.count != share->fields)
772
fix_type_pointers(&interval_array, share->intervals, interval_count,
776
/* Set ENUM and SET lengths */
778
for (interval= share->intervals;
779
interval < share->intervals + interval_count;
782
uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
783
if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
786
for (count= 0; count < interval->count; count++)
788
char *val= (char*) interval->type_names[count];
789
interval->type_lengths[count]= strlen(val);
791
interval->type_lengths[count]= 0;
796
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
798
/* Allocate handler */
799
if (!(handler_file= get_new_handler(share, thd->mem_root,
803
record= share->default_values-1; /* Fieldstart = 1 */
804
if (share->null_field_first)
806
null_flags= null_pos= (unsigned char*) record+1;
807
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
809
null_bytes below is only correct under the condition that
810
there are no bit fields. Correct values is set below after the
811
table struct is initialized
813
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
816
use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
818
use_hash= !hash_init(&share->name_hash,
821
(hash_get_key) get_field_name,0,0);
823
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
825
uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
enum_field_types field_type;
827
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
const CHARSET_INFO *charset= NULL;
831
if (field_extra_info)
833
char tmp= field_extra_info[i];
834
column_format= (enum column_format_type)
835
((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
837
if (new_frm_ver >= 3)
839
/* new frm file in 4.1 */
840
field_length= uint2korr(strpos+3);
841
recpos= uint3korr(strpos+5);
842
pack_flag= uint2korr(strpos+8);
843
unireg_type= (uint) strpos[10];
844
interval_nr= (uint) strpos[12];
845
uint32_t comment_length=uint2korr(strpos+15);
846
field_type=(enum_field_types) (uint) strpos[13];
850
charset= &my_charset_bin;
851
else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
853
error= 5; // Unknown or unavailable charset
854
errarg= (int) strpos[14];
860
comment.str= (char*) "";
865
comment.str= (char*) comment_pos;
866
comment.length= comment_length;
867
comment_pos+= comment_length;
872
field_length= (uint) strpos[3];
873
recpos= uint2korr(strpos+4),
874
pack_flag= uint2korr(strpos+6);
875
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
876
unireg_type= (uint) strpos[8];
877
interval_nr= (uint) strpos[10];
880
field_type= (enum_field_types) f_packtype(pack_flag);
881
if (f_is_binary(pack_flag))
884
Try to choose the best 4.1 type:
885
- for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
886
try to find a binary collation for character set.
887
- for other types (e.g. BLOB) just use my_charset_bin.
889
if (!f_is_blob(pack_flag))
891
// 3.23 or 4.0 string
892
if (!(charset= get_charset_by_csname(share->table_charset->csname,
893
MY_CS_BINSORT, MYF(0))))
894
charset= &my_charset_bin;
897
charset= &my_charset_bin;
900
charset= share->table_charset;
901
memset(&comment, 0, sizeof(comment));
904
if (interval_nr && charset->mbminlen > 1)
906
/* Unescape UCS2 intervals from HEX notation */
907
TYPELIB *interval= share->intervals + interval_nr - 1;
908
unhex_type2(interval);
911
*field_ptr= reg_field=
912
make_field(share, record+recpos,
913
(uint32_t) field_length,
914
null_pos, null_bit_pos,
918
(Field::utype) MTYP_TYPENR(unireg_type),
920
share->intervals+interval_nr-1 :
922
share->fieldnames.type_names[i]);
923
if (!reg_field) // Not supported field type
926
goto err; /* purecov: inspected */
929
reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
930
reg_field->field_index= i;
931
reg_field->comment=comment;
932
if (!(reg_field->flags & NOT_NULL_FLAG))
934
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
937
if (f_no_default(pack_flag))
938
reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
940
if (reg_field->unireg_check == Field::NEXT_NUMBER)
941
share->found_next_number_field= field_ptr;
942
if (share->timestamp_field == reg_field)
943
share->timestamp_field_offset= i;
946
(void) my_hash_insert(&share->name_hash,
947
(unsigned char*) field_ptr); // never fail
949
*field_ptr=0; // End marker
951
/* Fix key->name and key_part->field */
954
uint32_t primary_key=(uint) (find_type((char*) primary_key_name,
955
&share->keynames, 3) - 1);
956
int64_t ha_option= handler_file->ha_table_flags();
957
keyinfo= share->key_info;
958
key_part= keyinfo->key_part;
960
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
962
uint32_t usable_parts= 0;
963
keyinfo->name=(char*) share->keynames.type_names[key];
965
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
968
If the UNIQUE key doesn't have NULL columns and is not a part key
969
declare this as a primary key.
972
for (i=0 ; i < keyinfo->key_parts ;i++)
974
uint32_t fieldnr= key_part[i].fieldnr;
976
share->field[fieldnr-1]->null_ptr ||
977
share->field[fieldnr-1]->key_length() !=
980
primary_key=MAX_KEY; // Can't be used
986
for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
989
if (new_field_pack_flag <= 1)
990
key_part->fieldnr= (uint16_t) find_field(share->field,
991
share->default_values,
992
(uint) key_part->offset,
993
(uint) key_part->length);
994
if (!key_part->fieldnr)
996
error= 4; // Wrong file
999
field= key_part->field= share->field[key_part->fieldnr-1];
1000
key_part->type= field->key_type();
1001
if (field->null_ptr)
1003
key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1004
share->default_values);
1005
key_part->null_bit= field->null_bit;
1006
key_part->store_length+=HA_KEY_NULL_LENGTH;
1007
keyinfo->flags|=HA_NULL_PART_KEY;
1008
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1009
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1011
if (field->type() == DRIZZLE_TYPE_BLOB ||
1012
field->real_type() == DRIZZLE_TYPE_VARCHAR)
1014
if (field->type() == DRIZZLE_TYPE_BLOB)
1015
key_part->key_part_flag|= HA_BLOB_PART;
1017
key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1018
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1019
key_part->store_length+=HA_KEY_BLOB_LENGTH;
1020
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1022
if (i == 0 && key != primary_key)
1023
field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1024
(keyinfo->key_parts == 1)) ?
1025
UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1027
field->key_start.set_bit(key);
1028
if (field->key_length() == key_part->length &&
1029
!(field->flags & BLOB_FLAG))
1031
if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1033
share->keys_for_keyread.set_bit(key);
1034
field->part_of_key.set_bit(key);
1035
field->part_of_key_not_clustered.set_bit(key);
1037
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1038
field->part_of_sortkey.set_bit(key);
1040
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1042
usable_parts++; // For FILESORT
1043
field->flags|= PART_KEY_FLAG;
1044
if (key == primary_key)
1046
field->flags|= PRI_KEY_FLAG;
1048
If this field is part of the primary key and all keys contains
1049
the primary key, then we can use any key to find this column
1051
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1053
field->part_of_key= share->keys_in_use;
1054
if (field->part_of_sortkey.is_set(key))
1055
field->part_of_sortkey= share->keys_in_use;
1058
if (field->key_length() != key_part->length)
1060
key_part->key_part_flag|= HA_PART_KEY_SEG;
1063
keyinfo->usable_key_parts= usable_parts; // Filesort
1065
set_if_bigger(share->max_key_length,keyinfo->key_length+
1066
keyinfo->key_parts);
1067
share->total_key_length+= keyinfo->key_length;
1069
MERGE tables do not have unique indexes. But every key could be
1070
an unique index on the underlying MyISAM table. (Bug #10400)
1072
if ((keyinfo->flags & HA_NOSAME) ||
1073
(ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1074
set_if_bigger(share->max_unique_length,keyinfo->key_length);
1076
if (primary_key < MAX_KEY &&
1077
(share->keys_in_use.is_set(primary_key)))
1079
share->primary_key= primary_key;
1081
If we are using an integer as the primary key then allow the user to
1082
refer to it as '_rowid'
1084
if (share->key_info[primary_key].key_parts == 1)
1086
Field *field= share->key_info[primary_key].key_part[0].field;
1087
if (field && field->result_type() == INT_RESULT)
1089
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
1090
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1096
share->primary_key = MAX_KEY; // we do not have a primary key
1099
share->primary_key= MAX_KEY;
1103
if (new_field_pack_flag <= 1)
1105
/* Old file format with default as not null */
1106
uint32_t null_length= (share->null_fields+7)/8;
1107
memset(share->default_values + (null_flags - (unsigned char*) record),
1111
if (share->found_next_number_field)
1113
reg_field= *share->found_next_number_field;
1114
if ((int) (share->next_number_index= (uint)
1115
find_ref_key(share->key_info, share->keys,
1116
share->default_values, reg_field,
1117
&share->next_number_key_offset,
1118
&share->next_number_keypart)) < 0)
1120
/* Wrong field definition */
1125
reg_field->flags |= AUTO_INCREMENT_FLAG;
1128
if (share->blob_fields)
1133
/* Store offsets to blob fields to find them fast */
1134
if (!(share->blob_field= save=
1135
(uint*) alloc_root(&share->mem_root,
1136
(uint) (share->blob_fields* sizeof(uint)))))
1138
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1140
if ((*ptr)->flags & BLOB_FLAG)
1146
the correct null_bytes can now be set, since bitfields have been taken
1149
share->null_bytes= (null_pos - (unsigned char*) null_flags +
1150
(null_bit_pos + 7) / 8);
1151
share->last_null_bit_pos= null_bit_pos;
1153
share->db_low_byte_first= handler_file->low_byte_first();
1154
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1156
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1157
share->column_bitmap_size)))
1159
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1160
bitmap_set_all(&share->all_set);
1162
delete handler_file;
1170
share->error= error;
1171
share->open_errno= my_errno;
1172
share->errarg= errarg;
1175
delete handler_file;
1176
hash_free(&share->name_hash);
1178
open_table_error(share, error, share->open_errno, errarg);
1180
} /* open_binary_frm */
1184
Open a table based on a TABLE_SHARE
1187
open_table_from_share()
1189
share Table definition
1190
alias Alias for table
1191
db_stat open flags (for example HA_OPEN_KEYFILE|
1192
HA_OPEN_RNDFILE..) can be 0 (example in
1194
prgflag READ_ALL etc..
1195
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1196
outparam result table
1197
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1198
if OTM_CREATE some errors are ignore
1199
if OTM_ALTER HA_OPEN is not called
1203
1 Error (see open_table_error)
1204
2 Error (see open_table_error)
1205
3 Wrong data in .frm file
1206
4 Error (see open_table_error)
1207
5 Error (see open_table_error: charset unavailable)
1208
7 Table definition has changed in engine
1211
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1212
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1213
Table *outparam, open_table_mode open_mode)
1216
uint32_t records, i, bitmap_size;
1217
bool error_reported= false;
1218
unsigned char *record, *bitmaps;
1221
/* Parsing of partitioning information from .frm needs thd->lex set up. */
1222
assert(thd->lex->is_lex_started);
1225
memset(outparam, 0, sizeof(*outparam));
1226
outparam->in_use= thd;
1228
outparam->db_stat= db_stat;
1229
outparam->write_row_record= NULL;
1231
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1233
if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
1235
outparam->quick_keys.init();
1236
outparam->covering_keys.init();
1237
outparam->keys_in_use_for_query.init();
1239
/* Allocate handler */
1241
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1243
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1253
outparam->reginfo.lock_type= TL_UNLOCK;
1254
outparam->current_lock= F_UNLCK;
1256
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1258
if (prgflag & (READ_ALL+EXTRA_RECORD))
1261
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1262
share->rec_buff_length * records)))
1263
goto err; /* purecov: inspected */
1267
/* We are probably in hard repair, and the buffers should not be used */
1268
outparam->record[0]= outparam->record[1]= share->default_values;
1272
outparam->record[0]= record;
1274
outparam->record[1]= record+ share->rec_buff_length;
1276
outparam->record[1]= outparam->record[0]; // Safety
1281
We need this because when we read var-length rows, we are not updating
1282
bytes after end of varchar
1286
memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1287
memcpy(outparam->record[1], share->default_values, share->null_bytes);
1289
memcpy(outparam->record[1], share->default_values,
1290
share->rec_buff_length);
1294
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1295
(uint) ((share->fields+1)*
1297
goto err; /* purecov: inspected */
1299
outparam->field= field_ptr;
1301
record= (unsigned char*) outparam->record[0]-1; /* Fieldstart = 1 */
1302
if (share->null_field_first)
1303
outparam->null_flags= (unsigned char*) record+1;
1305
outparam->null_flags= (unsigned char*) (record+ 1+ share->reclength -
1308
/* Setup copy of fields from share, but use the right alias and record */
1309
for (i=0 ; i < share->fields; i++, field_ptr++)
1311
if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1314
(*field_ptr)= 0; // End marker
1316
if (share->found_next_number_field)
1317
outparam->found_next_number_field=
1318
outparam->field[(uint) (share->found_next_number_field - share->field)];
1319
if (share->timestamp_field)
1320
outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1323
/* Fix key->name and key_part->field */
1324
if (share->key_parts)
1326
KEY *key_info, *key_info_end;
1327
KEY_PART_INFO *key_part;
1329
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1330
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1332
outparam->key_info= key_info;
1333
key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1335
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1336
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1339
for (key_info_end= key_info + share->keys ;
1340
key_info < key_info_end ;
1343
KEY_PART_INFO *key_part_end;
1345
key_info->table= outparam;
1346
key_info->key_part= key_part;
1348
for (key_part_end= key_part+ key_info->key_parts ;
1349
key_part < key_part_end ;
1352
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1354
if (field->key_length() != key_part->length &&
1355
!(field->flags & BLOB_FLAG))
1358
We are using only a prefix of the column as a key:
1359
Create a new field for the key part that matches the index
1361
field= key_part->field=field->new_field(&outparam->mem_root,
1363
field->field_length= key_part->length;
1369
/* Allocate bitmaps */
1371
bitmap_size= share->column_bitmap_size;
1372
if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1374
bitmap_init(&outparam->def_read_set,
1375
(my_bitmap_map*) bitmaps, share->fields, false);
1376
bitmap_init(&outparam->def_write_set,
1377
(my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1378
bitmap_init(&outparam->tmp_set,
1379
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1380
outparam->default_column_bitmaps();
1382
/* The table struct is now initialized; Open the table */
1384
if (db_stat && open_mode != OTM_ALTER)
1387
if ((ha_err= (outparam->file->
1388
ha_open(outparam, share->normalized_path.str,
1389
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1390
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1391
(db_stat & HA_WAIT_IF_LOCKED) ? HA_OPEN_WAIT_IF_LOCKED :
1392
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1393
HA_OPEN_ABORT_IF_LOCKED :
1394
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1396
/* Set a flag if the table is crashed and it can be auto. repaired */
1397
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1398
outparam->file->auto_repair() &&
1399
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
1403
case HA_ERR_NO_SUCH_TABLE:
1405
The table did not exists in storage engine, use same error message
1406
as if the .frm file didn't exist
1413
Too many files opened, use same error message as if the .frm
1420
outparam->file->print_error(ha_err, MYF(0));
1421
error_reported= true;
1422
if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1426
goto err; /* purecov: inspected */
1430
#if defined(HAVE_purify)
1431
memset(bitmaps, 0, bitmap_size*3);
1434
outparam->no_replicate= outparam->file;
1435
thd->status_var.opened_tables++;
1440
if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1441
open_table_error(share, error, my_errno, 0);
1442
delete outparam->file;
1443
outparam->file= 0; // For easier error checking
1444
outparam->db_stat=0;
1445
free_root(&outparam->mem_root, MYF(0)); // Safe to call on zeroed root
1446
free((char*) outparam->alias);
1452
Free information allocated by openfrm
1456
table Table object to free
1457
free_share Is 1 if we also want to free table_share
1460
int closefrm(register Table *table, bool free_share)
1465
error=table->file->close();
1466
free((char*) table->alias);
1470
for (Field **ptr=table->field ; *ptr ; ptr++)
95
cursor= 0; /* For easier errorchecking */
1475
table->file= 0; /* For easier errorchecking */
99
if (s->getType() == message::Table::STANDARD)
101
TableShare::release(s);
1478
if (table->s->tmp_table == NO_TMP_TABLE)
1479
release_table_share(table->s, RELEASE_NORMAL);
1481
free_table_share(table->s);
110
mem_root.free_root(MYF(0));
116
void Table::resetTable(Session *session,
118
uint32_t db_stat_arg)
131
db_stat= db_stat_arg;
134
record[0]= (unsigned char *) NULL;
135
record[1]= (unsigned char *) NULL;
137
insert_values.clear();
139
next_number_field= NULL;
140
found_next_number_field= NULL;
141
timestamp_field= NULL;
143
pos_in_table_list= NULL;
153
derived_select_number= 0;
154
current_lock= F_UNLCK;
168
open_placeholder= false;
169
locked_by_name= false;
172
auto_increment_field_not_null= false;
173
alias_name_used= false;
176
quick_condition_rows= 0;
178
timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
183
covering_keys.reset();
188
keys_in_use_for_query.reset();
189
keys_in_use_for_group_by.reset();
190
keys_in_use_for_order_by.reset();
192
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
193
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
195
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
196
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
198
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1483
free_root(&table->mem_root, MYF(0));
203
1488
/* Deallocate temporary blob storage */
208
1493
for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
212
((Field_blob*) table->getField(*ptr))->free();
217
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
219
TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
1496
((Field_blob*) table->field[*ptr])->free();
1500
/* Find where a form starts */
1501
/* if formname is NULL then only formnames is read */
1503
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
1505
uint32_t a_length,names,length;
1506
unsigned char *pos,*buf;
1509
names=uint2korr(head+8);
1510
a_length=(names+2)*sizeof(char *); /* Room for two extra */
1515
save_names->type_names=0; /* Clear if error */
1519
length=uint2korr(head+4);
1520
my_seek(file,64L,MY_SEEK_SET,MYF(0));
1521
if (!(buf= (unsigned char*) my_malloc((size_t) length+a_length+names*4,
1523
my_read(file, buf+a_length, (size_t) (length+names*4),
1525
{ /* purecov: inspected */
1528
return(0L); /* purecov: inspected */
1530
pos= buf+a_length+length;
1531
ret_value=uint4korr(pos);
1536
free((unsigned char*) buf);
1539
memset(save_names, 0, sizeof(save_names));
1543
str=(char *) (buf+a_length);
1544
fix_type_pointers((const char ***) &buf,save_names,1,&str);
1551
Read string from a file with malloc
1554
We add an \0 at end of the read string to make reading of C strings easier
1557
int read_string(File file, unsigned char**to, size_t length)
1562
if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
1563
my_read(file, *to, length,MYF(MY_NABP)))
1568
return(1); /* purecov: inspected */
1570
*((char*) *to+length)= '\0';
1575
/* Add a new form to a form file */
1577
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1578
const char *newname)
1580
uint32_t i,bufflength,maxlength,n_length,length,names;
1581
ulong endpos,newpos;
1582
unsigned char buff[IO_SIZE];
1585
length=(uint) strlen(newname)+1;
1586
n_length=uint2korr(fileinfo+4);
1587
maxlength=uint2korr(fileinfo+6);
1588
names=uint2korr(fileinfo+8);
1589
newpos=uint4korr(fileinfo+10);
1591
if (64+length+n_length+(names+1)*4 > maxlength)
1594
int4store(fileinfo+10,newpos);
1595
endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1596
bufflength= (uint) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */
1598
while (endpos > maxlength)
1600
my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
1601
if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1603
my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1605
if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1607
endpos-=bufflength; bufflength=IO_SIZE;
1609
memset(buff, 0, IO_SIZE); /* Null new block */
1610
my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
1611
if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1613
maxlength+=IO_SIZE; /* Fix old ref */
1614
int2store(fileinfo+6,maxlength);
1615
for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1618
endpos=uint4korr(pos)+IO_SIZE;
1619
int4store(pos,endpos);
1626
strxmov((char*) buff,"/",newname,"/",NULL);
1629
strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
1630
my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
1631
if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1632
(names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1633
names*4, MYF(MY_NABP+MY_WME))) ||
1634
my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1635
return(0L); /* purecov: inspected */
1637
int2store(fileinfo+8,names+1);
1638
int2store(fileinfo+4,n_length+length);
1639
(void)ftruncate(file, newpos);/* Append file with '\0' */
1641
} /* make_new_entry */
1644
/* error message when opening a form file */
1646
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1649
char buff[FN_REFLEN];
1650
myf errortype= ME_ERROR+ME_WAITTANG;
1655
if (db_errno == ENOENT)
1656
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1659
strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1660
my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1661
errortype, buff, db_errno);
1667
const char *datext= "";
1669
if (share->db_type() != NULL)
1671
if ((file= get_new_handler(share, current_thd->mem_root,
1674
if (!(datext= *file->bas_ext()))
1678
err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1679
ER_FILE_USED : ER_CANT_OPEN_FILE;
1680
strxmov(buff, share->normalized_path.str, datext, NULL);
1681
my_error(err_no,errortype, buff, db_errno);
1687
const char *csname= get_charset_name((uint) errarg);
1689
if (!csname || csname[0] =='?')
1691
snprintf(tmp, sizeof(tmp), "#%d", errarg);
1694
my_printf_error(ER_UNKNOWN_COLLATION,
1695
_("Unknown collation '%s' in table '%-.64s' definition"),
1696
MYF(0), csname, share->table_name.str);
1700
strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1701
my_printf_error(ER_NOT_FORM_FILE,
1702
_("Table '%-.64s' was created with a different version "
1703
"of MySQL and cannot be read"),
1708
default: /* Better wrong error than none */
1710
strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1711
my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1715
} /* open_table_error */
1719
** fix a str_type to a array type
1720
** typeparts separated with some char. differents types are separated
1725
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
1728
char *type_name, *ptr;
1734
point_to_type->name=0;
1735
point_to_type->type_names= *array;
1737
if ((chr= *ptr)) /* Test if empty type */
1739
while ((type_name=strchr(ptr+1,chr)) != NULL)
1741
*((*array)++) = ptr+1;
1742
*type_name= '\0'; /* End string */
1745
ptr+=2; /* Skip end mark and last 0 */
1749
point_to_type->count= (uint) (*array - point_to_type->type_names);
1751
*((*array)++)= NULL; /* End of type */
1753
*names=ptr; /* Update end */
1755
} /* fix_type_pointers */
1758
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1760
TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
222
result->count= strings.elements;
224
uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
226
if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
1763
result->count=strings.elements;
1765
uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1766
if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
229
1768
result->type_lengths= (uint*) (result->type_names + result->count + 1);
231
1769
List_iterator<String> it(strings);
233
for (uint32_t i= 0; (tmp= it++); i++)
1771
for (uint32_t i=0; (tmp=it++) ; i++)
235
1773
result->type_names[i]= tmp->ptr();
236
1774
result->type_lengths[i]= tmp->length();
239
result->type_names[result->count]= 0; // End marker
1776
result->type_names[result->count]= 0; // End marker
240
1777
result->type_lengths[result->count]= 0;
1783
Search after a field with given start & length
1784
If an exact field isn't found, return longest field with starts
1788
This is needed because in some .frm fields 'fieldnr' was saved wrong
1795
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length)
1801
for (field= fields, i=1 ; *field ; i++,field++)
1803
if ((*field)->offset(record) == start)
1805
if ((*field)->key_length() == length)
1807
if (!pos || fields[pos-1]->pack_length() <
1808
(*field)->pack_length())
245
1816
/* Check that the integer is in the internal */
247
1818
int set_zone(register int nr, int min_zone, int max_zone)
437
2240
/* Error if empty or too long column name */
438
return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2241
return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2246
Checks whether a table is intact. Should be done *just* after the table has
2249
@param[in] table The table to check
2250
@param[in] table_f_count Expected number of columns in the table
2251
@param[in] table_def Expected structure of the table (column name
2255
@retval TRUE There was an error. An error message is output
2256
to the error log. We do not push an error
2257
message into the error stack because this
2258
function is currently only called at start up,
2259
and such errors never reach the user.
2263
Table::table_check_intact(const uint32_t table_f_count,
2264
const TABLE_FIELD_W_TYPE *table_def)
2268
bool fields_diff_count;
2270
fields_diff_count= (s->fields != table_f_count);
2271
if (fields_diff_count)
2274
/* previous MySQL version */
2275
if (DRIZZLE_VERSION_ID > s->mysql_version)
2277
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2278
alias, table_f_count, s->fields,
2279
s->mysql_version, DRIZZLE_VERSION_ID);
2282
else if (DRIZZLE_VERSION_ID == s->mysql_version)
2284
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2285
table_f_count, s->fields);
2289
Something has definitely changed, but we're running an older
2290
version of MySQL with new system tables.
2291
Let's check column definitions. If a column was added at
2292
the end of the table, then we don't care much since such change
2293
is backward compatible.
2296
char buffer[STRING_BUFFER_USUAL_SIZE];
2297
for (i=0 ; i < table_f_count; i++, table_def++)
2299
String sql_type(buffer, sizeof(buffer), system_charset_info);
2303
Field *field= this->field[i];
2305
if (strncmp(field->field_name, table_def->name.str,
2306
table_def->name.length))
2309
Name changes are not fatal, we use ordinal numbers to access columns.
2310
Still this can be a sign of a tampered table, output an error
2313
sql_print_error(_("Incorrect definition of table %s.%s: "
2314
"expected column '%s' at position %d, found '%s'."),
2315
s->db.str, alias, table_def->name.str, i,
2318
field->sql_type(sql_type);
2320
Generally, if column types don't match, then something is
2323
However, we only compare column definitions up to the
2324
length of the original definition, since we consider the
2325
following definitions compatible:
2327
1. DATETIME and DATETIM
2328
2. INT(11) and INT(11
2329
3. SET('one', 'two') and SET('one', 'two', 'more')
2331
For SETs or ENUMs, if the same prefix is there it's OK to
2332
add more elements - they will get higher ordinal numbers and
2333
the new table definition is backward compatible with the
2336
if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2337
table_def->type.length - 1))
2339
sql_print_error(_("Incorrect definition of table %s.%s: "
2340
"expected column '%s' at position %d to have type "
2341
"%s, found type %s."), s->db.str, alias,
2342
table_def->name.str, i, table_def->type.str,
2343
sql_type.c_ptr_safe());
2346
else if (table_def->cset.str && !field->has_charset())
2348
sql_print_error(_("Incorrect definition of table %s.%s: "
2349
"expected the type of column '%s' at position %d "
2350
"to have character set '%s' but the type has no "
2351
"character set."), s->db.str, alias,
2352
table_def->name.str, i, table_def->cset.str);
2355
else if (table_def->cset.str &&
2356
strcmp(field->charset()->csname, table_def->cset.str))
2358
sql_print_error(_("Incorrect definition of table %s.%s: "
2359
"expected the type of column '%s' at position %d "
2360
"to have character set '%s' but found "
2361
"character set '%s'."), s->db.str, alias,
2362
table_def->name.str, i, table_def->cset.str,
2363
field->charset()->csname);
2369
sql_print_error(_("Incorrect definition of table %s.%s: "
2370
"expected column '%s' at position %d to have type %s "
2371
" but the column is not found."),
2373
table_def->name.str, i, table_def->type.str);
2382
Create Item_field for each column in the table.
2385
Table::fill_item_list()
2386
item_list a pointer to an empty list used to store items
2389
Create Item_field object for each column in the table and
2390
initialize it with the corresponding Field. New items are
2391
created in the current THD memory root.
2398
bool Table::fill_item_list(List<Item> *item_list) const
2401
All Item_field's created using a direct pointer to a field
2402
are fixed in Item_field constructor.
2404
for (Field **ptr= field; *ptr; ptr++)
2406
Item_field *item= new Item_field(*ptr);
2407
if (!item || item_list->push_back(item))
2414
Reset an existing list of Item_field items to point to the
2415
Fields of this table.
2418
Table::fill_item_list()
2419
item_list a non-empty list with Item_fields
2422
This is a counterpart of fill_item_list used to redirect
2423
Item_fields to the fields of a newly created table.
2424
The caller must ensure that number of items in the item_list
2425
is the same as the number of columns in the table.
2428
void Table::reset_item_list(List<Item> *item_list) const
2430
List_iterator_fast<Item> it(*item_list);
2431
for (Field **ptr= field; *ptr; ptr++)
2433
Item_field *item_field= (Item_field*) it++;
2434
assert(item_field != 0);
2435
item_field->reset_field(*ptr);
2441
Find underlying base tables (TableList) which represent given
2442
table_to_find (Table)
2445
TableList::find_underlying_table()
2446
table_to_find table to find
2449
0 table is not found
2450
found table reference
2453
TableList *TableList::find_underlying_table(Table *table_to_find)
2455
/* is this real table and table which we are looking for? */
2456
if (table == table_to_find && merge_underlying_list == 0)
2459
for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2462
if ((result= tbl->find_underlying_table(table_to_find)))
2469
cleunup items belonged to view fields translation table
2472
TableList::cleanup_items()
2475
void TableList::cleanup_items()
2477
if (!field_translation)
2480
for (Field_translator *transl= field_translation;
2481
transl < field_translation_end;
2483
transl->item->walk(&Item::cleanup_processor, 0, 0);
2488
Set insert_values buffer
2492
mem_root memory pool for allocating
2496
TRUE - out of memory
2499
bool TableList::set_insert_values(MEM_ROOT *mem_root)
2503
if (!table->insert_values &&
2504
!(table->insert_values= (unsigned char *)alloc_root(mem_root,
2505
table->s->rec_buff_length)))
2514
Test if this is a leaf with respect to name resolution.
2517
TableList::is_leaf_for_name_resolution()
2520
A table reference is a leaf with respect to name resolution if
2521
it is either a leaf node in a nested join tree (table, view,
2522
schema table, subquery), or an inner node that represents a
2523
NATURAL/USING join, or a nested join with materialized join
2527
TRUE if a leaf, false otherwise.
2529
bool TableList::is_leaf_for_name_resolution()
2531
return (is_natural_join || is_join_columns_complete || !nested_join);
2536
Retrieve the first (left-most) leaf in a nested join tree with
2537
respect to name resolution.
2540
TableList::first_leaf_for_name_resolution()
2543
Given that 'this' is a nested table reference, recursively walk
2544
down the left-most children of 'this' until we reach a leaf
2545
table reference with respect to name resolution.
2548
The left-most child of a nested table reference is the last element
2549
in the list of children because the children are inserted in
2553
If 'this' is a nested table reference - the left-most child of
2554
the tree rooted in 'this',
2558
TableList *TableList::first_leaf_for_name_resolution()
2560
TableList *cur_table_ref= NULL;
2561
nested_join_st *cur_nested_join;
2563
if (is_leaf_for_name_resolution())
2565
assert(nested_join);
2567
for (cur_nested_join= nested_join;
2569
cur_nested_join= cur_table_ref->nested_join)
2571
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2572
cur_table_ref= it++;
2574
If the current nested join is a RIGHT JOIN, the operands in
2575
'join_list' are in reverse order, thus the first operand is
2576
already at the front of the list. Otherwise the first operand
2577
is in the end of the list of join operands.
2579
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2582
while ((next= it++))
2583
cur_table_ref= next;
2585
if (cur_table_ref->is_leaf_for_name_resolution())
2588
return cur_table_ref;
2593
Retrieve the last (right-most) leaf in a nested join tree with
2594
respect to name resolution.
2597
TableList::last_leaf_for_name_resolution()
2600
Given that 'this' is a nested table reference, recursively walk
2601
down the right-most children of 'this' until we reach a leaf
2602
table reference with respect to name resolution.
2605
The right-most child of a nested table reference is the first
2606
element in the list of children because the children are inserted
2610
- If 'this' is a nested table reference - the right-most child of
2611
the tree rooted in 'this',
2615
TableList *TableList::last_leaf_for_name_resolution()
2617
TableList *cur_table_ref= this;
2618
nested_join_st *cur_nested_join;
2620
if (is_leaf_for_name_resolution())
2622
assert(nested_join);
2624
for (cur_nested_join= nested_join;
2626
cur_nested_join= cur_table_ref->nested_join)
2628
cur_table_ref= cur_nested_join->join_list.head();
2630
If the current nested is a RIGHT JOIN, the operands in
2631
'join_list' are in reverse order, thus the last operand is in the
2634
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2636
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2638
cur_table_ref= it++;
2639
while ((next= it++))
2640
cur_table_ref= next;
2642
if (cur_table_ref->is_leaf_for_name_resolution())
2645
return cur_table_ref;