16
16
/* open a isam-database */
18
#include "myisam_priv.h"
18
#include "myisamdef.h"
19
#include <mystrings/m_ctype.h>
20
#include <mystrings/m_string.h>
21
#include <drizzled/util/test.h>
20
23
#include <string.h>
21
24
#include <algorithm>
23
#include "drizzled/charset_info.h"
24
#include "drizzled/internal/m_string.h"
25
#include "drizzled/util/test.h"
26
#include "drizzled/global_charset_info.h"
27
#include "drizzled/charset.h"
28
#include "drizzled/memory/multi_malloc.h"
31
26
using namespace std;
32
using namespace drizzled;
34
28
static void setup_key_functions(MI_KEYDEF *keyinfo);
35
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
36
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg);
37
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo);
38
static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
39
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state);
40
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def);
41
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base);
43
30
#define disk_pos_assert(pos, end_pos) \
44
31
if (pos > end_pos) \
46
errno=HA_ERR_CRASHED; \
33
my_errno=HA_ERR_CRASHED; \
97
84
head_length=sizeof(share_buff.state.header);
98
85
memset(&info, 0, sizeof(info));
100
(void)internal::fn_format(org_name,name,"",MI_NAME_IEXT, MY_UNPACK_FILENAME);
87
(void)fn_format(org_name,name,"",MI_NAME_IEXT, MY_UNPACK_FILENAME);
101
88
if (!realpath(org_name,rp_buff))
102
internal::my_load_path(rp_buff,org_name, NULL);
89
my_load_path(rp_buff,org_name, NULL);
103
90
rp_buff[FN_REFLEN-1]= '\0';
104
91
strcpy(name_buff,rp_buff);
105
92
pthread_mutex_lock(&THR_LOCK_myisam);
112
99
share_buff.state.key_del=key_del;
113
100
share_buff.key_cache= dflt_key_cache;
115
if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
102
if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
117
104
if ((errno != EROFS && errno != EACCES) ||
118
105
mode != O_RDONLY ||
119
(kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
106
(kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
122
109
share->mode=open_mode;
124
if (internal::my_read(kfile, share->state.header.file_version, head_length,
111
if (my_read(kfile, share->state.header.file_version, head_length,
127
errno= HA_ERR_NOT_A_TABLE;
114
my_errno= HA_ERR_NOT_A_TABLE;
130
117
if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
132
errno=HA_ERR_NOT_A_TABLE;
119
my_errno=HA_ERR_NOT_A_TABLE;
135
122
share->options= mi_uint2korr(share->state.header.options);
151
138
if (!strcmp(name_buff, org_name) || sym_link_size == -1)
152
139
(void) strcpy(index_name, org_name);
153
140
*strrchr(org_name, '.')= '\0';
154
(void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
141
(void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
155
142
MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
157
144
info_length=mi_uint2korr(share->state.header.header_length);
158
145
base_pos=mi_uint2korr(share->state.header.base_pos);
159
146
if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
164
151
end_pos=disk_cache+info_length;
184
171
disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
185
172
share->state.state_length=base_pos;
187
if (share->state.changed & STATE_CRASHED)
174
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
175
((share->state.changed & STATE_CRASHED) ||
176
((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
177
(share->state.open_count))))
189
errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
179
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
190
180
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
221
211
if (share->base.raid_type)
223
errno=HA_ERR_UNSUPPORTED;
213
my_errno=HA_ERR_UNSUPPORTED;
226
share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
227
share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
216
share->base.max_data_file_length=(my_off_t) max_data_file_length;
217
share->base.max_key_file_length=(my_off_t) max_key_file_length;
229
219
if (share->options & HA_OPTION_COMPRESS_RECORD)
230
220
share->base.max_key_length+=2; /* For safety */
232
222
/* Add space for node pointer */
233
223
share->base.max_key_length+= share->base.key_reflength;
235
if (!drizzled::memory::multi_malloc(false,
236
&share,sizeof(*share),
237
&share->state.rec_per_key_part,sizeof(long)*key_parts,
238
&share->keyinfo,keys*sizeof(MI_KEYDEF),
239
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
241
(key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
242
&share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
243
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
244
&share->unique_file_name,strlen(name_buff)+1,
245
&share->index_file_name,strlen(index_name)+1,
246
&share->data_file_name,strlen(data_name)+1,
247
&share->state.key_root,keys*sizeof(uint64_t),
248
&share->state.key_del,
249
(share->state.header.max_block_size_index*sizeof(uint64_t)),
250
&share->key_root_lock,sizeof(pthread_rwlock_t)*keys,
251
&share->mmap_lock,sizeof(pthread_rwlock_t),
225
if (!my_multi_malloc(MY_WME,
226
&share,sizeof(*share),
227
&share->state.rec_per_key_part,sizeof(long)*key_parts,
228
&share->keyinfo,keys*sizeof(MI_KEYDEF),
229
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
231
(key_parts+unique_key_parts+keys+uniques) *
234
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
235
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
236
&share->unique_file_name,strlen(name_buff)+1,
237
&share->index_file_name,strlen(index_name)+1,
238
&share->data_file_name,strlen(data_name)+1,
239
&share->state.key_root,keys*sizeof(my_off_t),
240
&share->state.key_del,
241
(share->state.header.max_block_size_index*sizeof(my_off_t)),
242
&share->key_root_lock,sizeof(pthread_rwlock_t)*keys,
243
&share->mmap_lock,sizeof(pthread_rwlock_t),
255
247
*share=share_buff;
256
248
memcpy(share->state.rec_per_key_part, rec_per_key_part,
257
249
sizeof(long)*key_parts);
258
250
memcpy(share->state.key_root, key_root,
259
sizeof(internal::my_off_t)*keys);
251
sizeof(my_off_t)*keys);
260
252
memcpy(share->state.key_del, key_del,
261
sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
253
sizeof(my_off_t) * share->state.header.max_block_size_index);
262
254
strcpy(share->unique_file_name, name_buff);
263
255
share->unique_name_length= strlen(name_buff);
264
256
strcpy(share->index_file_name, index_name);
433
425
/* alloc and set up private structure parts */
434
if (!drizzled::memory::multi_malloc(MY_WME,
435
&m_info,sizeof(MI_INFO),
436
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
437
&info.buff,(share->base.max_key_block_length*2+
438
share->base.max_key_length),
439
&info.lastkey,share->base.max_key_length*3+1,
440
&info.first_mbr_key, share->base.max_key_length,
441
&info.filename,strlen(name)+1,
442
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
426
if (!my_multi_malloc(MY_WME,
427
&m_info,sizeof(MI_INFO),
428
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
429
&info.buff,(share->base.max_key_block_length*2+
430
share->base.max_key_length),
431
&info.lastkey,share->base.max_key_length*3+1,
432
&info.first_mbr_key, share->base.max_key_length,
433
&info.filename,strlen(name)+1,
434
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
755
747
return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
756
748
MYF(MY_NABP | MY_THREADSAFE)) != 0);
757
return(internal::my_write(file, buff, (size_t) (ptr-buff),
749
return(my_write(file, buff, (size_t) (ptr-buff),
758
750
MYF(MY_NABP)) != 0);
762
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
754
unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
764
756
uint32_t i,keys,key_parts,key_blocks;
765
757
memcpy(&state->header,ptr, sizeof(state->header));
866
858
mi_int4store(ptr,UINT32_C(0)); ptr +=4;
868
860
memset(ptr, 0, 6); ptr +=6; /* extra */
869
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
861
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
873
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
865
unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
875
867
base->keystart = mi_sizekorr(ptr); ptr +=8;
876
868
base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
920
912
mi_int2store(ptr,keydef->keylength); ptr +=2;
921
913
mi_int2store(ptr,keydef->minlength); ptr +=2;
922
914
mi_int2store(ptr,keydef->maxlength); ptr +=2;
923
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
915
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
926
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
918
unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
928
920
keydef->keysegs = (uint) *ptr++;
929
921
keydef->key_alg = *ptr++; /* Rtree or Btree */
1002
994
*ptr++= (unsigned char) def->key;
1003
995
*ptr++ = (unsigned char) def->null_are_equal;
1005
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
997
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1008
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1000
unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1010
1002
def->keysegs = mi_uint2korr(ptr);
1011
1003
def->key = ptr[2];
1026
1018
mi_int2store(ptr,recinfo->length); ptr +=2;
1027
1019
*ptr++ = recinfo->null_bit;
1028
1020
mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
1029
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1021
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1032
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1024
unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1034
1026
recinfo->type= mi_sint2korr(ptr); ptr +=2;
1035
1027
recinfo->length=mi_uint2korr(ptr); ptr +=2;
1047
1039
exist a dup()-like call that would give us two different file descriptors.
1048
1040
*************************************************************************/
1050
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
1042
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup)
1052
1044
(void)file_to_dup;
1053
info->dfile=internal::my_open(share->data_file_name, share->mode,
1045
info->dfile=my_open(share->data_file_name, share->mode,
1055
1047
return info->dfile >= 0 ? 0 : 1;