12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/* open a isam-database */
18
#include "myisam_priv.h"
23
#include <boost/scoped_ptr.hpp>
24
#include <boost/scoped_array.hpp>
26
#include "drizzled/charset_info.h"
27
#include "drizzled/internal/m_string.h"
28
#include "drizzled/util/test.h"
29
#include "drizzled/global_charset_info.h"
30
#include "drizzled/charset.h"
31
#include "drizzled/memory/multi_malloc.h"
35
using namespace drizzled;
23
#if defined(MSDOS) || defined(__WIN__)
27
#include <process.h> /* Prototype for getpid */
37
34
static void setup_key_functions(MI_KEYDEF *keyinfo);
38
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
39
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg);
40
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo);
41
static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
42
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state);
43
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def);
44
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base);
35
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
46
39
#define disk_pos_assert(pos, end_pos) \
47
40
if (pos > end_pos) \
49
errno=HA_ERR_CRASHED; \
42
my_errno=HA_ERR_CRASHED; \
79
72
have an open count of 0.
80
73
******************************************************************************/
82
MI_INFO *mi_open(const drizzled::TableIdentifier &identifier, int mode, uint32_t open_flags)
75
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
84
77
int lock_error,kfile,open_mode,save_errno,have_rtree=0;
85
uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
78
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
86
79
key_parts,unique_key_parts,fulltext_keys,uniques;
87
80
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
88
data_name[FN_REFLEN], rp_buff[PATH_MAX];
89
unsigned char *disk_cache= NULL;
90
unsigned char *disk_pos, *end_pos;
82
uchar *disk_cache, *disk_pos, *end_pos;
91
83
MI_INFO info,*m_info,*old_info;
92
boost::scoped_ptr<MYISAM_SHARE> share_buff_ap(new MYISAM_SHARE);
93
MYISAM_SHARE &share_buff= *share_buff_ap.get();
95
boost::scoped_array<ulong> rec_per_key_part_ap(new ulong[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]);
96
ulong *rec_per_key_part= rec_per_key_part_ap.get();
97
internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
98
uint64_t max_key_file_length, max_data_file_length;
84
MYISAM_SHARE share_buff,*share;
85
ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
86
my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
87
ulonglong max_key_file_length, max_data_file_length;
88
DBUG_ENTER("mi_open");
103
93
head_length=sizeof(share_buff.state.header);
104
memset(&info, 0, sizeof(info));
94
bzero((uchar*) &info,sizeof(info));
106
(void)internal::fn_format(org_name,
107
identifier.getPath().c_str(),
111
if (!realpath(org_name,rp_buff))
112
internal::my_load_path(rp_buff,org_name, NULL);
113
rp_buff[FN_REFLEN-1]= '\0';
114
strcpy(name_buff,rp_buff);
115
THR_LOCK_myisam.lock();
96
my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
97
MY_UNPACK_FILENAME),MYF(0));
98
pthread_mutex_lock(&THR_LOCK_myisam);
116
99
if (!(old_info=test_if_reopen(name_buff)))
118
101
share= &share_buff;
119
memset(&share_buff, 0, sizeof(share_buff));
102
bzero((uchar*) &share_buff,sizeof(share_buff));
120
103
share_buff.state.rec_per_key_part=rec_per_key_part;
121
104
share_buff.state.key_root=key_root;
122
105
share_buff.state.key_del=key_del;
123
share_buff.setKeyCache();
106
share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
125
if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
109
DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
110
if (strstr(name, "/t1"))
112
my_errno= HA_ERR_CRASHED;
115
if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
127
117
if ((errno != EROFS && errno != EACCES) ||
128
118
mode != O_RDONLY ||
129
(kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
119
(kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
132
122
share->mode=open_mode;
134
if (internal::my_read(kfile, share->state.header.file_version, head_length,
124
if (my_read(kfile, share->state.header.file_version, head_length,
137
errno= HA_ERR_NOT_A_TABLE;
127
my_errno= HA_ERR_NOT_A_TABLE;
140
if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
130
if (memcmp((uchar*) share->state.header.file_version,
131
(uchar*) myisam_file_magic, 4))
142
errno=HA_ERR_NOT_A_TABLE;
133
DBUG_PRINT("error",("Wrong header in %s",name_buff));
134
DBUG_DUMP("error_dump",(uchar*) share->state.header.file_version,
136
my_errno=HA_ERR_NOT_A_TABLE;
145
139
share->options= mi_uint2korr(share->state.header.options);
146
static const uint64_t OLD_FILE_OPTIONS= HA_OPTION_PACK_RECORD |
147
HA_OPTION_PACK_KEYS |
148
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
149
HA_OPTION_TEMP_COMPRESS_RECORD |
151
if (share->options & ~OLD_FILE_OPTIONS)
153
errno=HA_ERR_OLD_FILE;
141
~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
142
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
143
HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
144
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
145
HA_OPTION_RELIES_ON_SQL_LAYER))
147
DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
148
my_errno=HA_ERR_OLD_FILE;
151
if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
152
! (open_flags & HA_OPEN_FROM_SQL_LAYER))
154
DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
155
my_errno= HA_ERR_UNSUPPORTED;
157
158
/* Don't call realpath() if the name can't be a link */
158
ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
159
if (sym_link_size >= 0 )
160
index_name[sym_link_size]= '\0';
161
if (!strcmp(name_buff, org_name) || sym_link_size == -1)
162
(void) strcpy(index_name, org_name);
159
if (!strcmp(name_buff, org_name) ||
160
my_readlink(index_name, org_name, MYF(0)) == -1)
161
(void) strmov(index_name, org_name);
163
162
*strrchr(org_name, '.')= '\0';
164
(void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
163
(void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
165
164
MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
167
166
info_length=mi_uint2korr(share->state.header.header_length);
168
167
base_pos=mi_uint2korr(share->state.header.base_pos);
169
if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
168
if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
174
173
end_pos=disk_cache+info_length;
177
lseek(kfile,0,SEEK_SET);
176
VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
177
if (!(open_flags & HA_OPEN_TMP_TABLE))
179
if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
180
MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
181
0 : MY_DONT_WAIT))) &&
182
!(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
179
if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
186
if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
181
errno=HA_ERR_CRASHED;
188
my_errno=HA_ERR_CRASHED;
184
191
len=mi_uint2korr(share->state.header.state_info_length);
187
194
fulltext_keys= (uint) share->state.header.fulltext_keys;
188
195
key_parts= mi_uint2korr(share->state.header.key_parts);
189
196
unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
197
if (len != MI_STATE_INFO_SIZE)
199
DBUG_PRINT("warning",
200
("saved_state_info_length: %d state_info_length: %d",
201
len,MI_STATE_INFO_SIZE));
190
203
share->state_diff_length=len-MI_STATE_INFO_SIZE;
192
205
mi_state_info_read(disk_cache, &share->state);
193
206
len= mi_uint2korr(share->state.header.base_info_length);
207
if (len != MI_BASE_INFO_SIZE)
209
DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d",
210
len,MI_BASE_INFO_SIZE));
194
212
disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
195
213
share->state.state_length=base_pos;
197
if (share->state.changed & STATE_CRASHED)
215
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
216
((share->state.changed & STATE_CRASHED) ||
217
((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
218
(my_disable_locking && share->state.open_count))))
199
errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
220
DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u "
221
"changed: %u open_count: %u !locking: %d",
222
open_flags, share->state.changed,
223
share->state.open_count, my_disable_locking));
224
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
200
225
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
204
229
/* sanity check */
205
230
if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
207
errno=HA_ERR_CRASHED;
232
my_errno=HA_ERR_CRASHED;
236
key_parts+=fulltext_keys*FT_SEGS;
211
237
if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
212
238
key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
214
errno=HA_ERR_UNSUPPORTED;
240
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
241
my_errno=HA_ERR_UNSUPPORTED;
218
245
/* Correct max_file_length based on length of sizeof(off_t) */
219
246
max_data_file_length=
220
247
(share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
221
(((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
248
(((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
222
249
(mi_safe_mul(share->base.pack_reclength,
223
(uint64_t) 1 << (share->base.rec_reflength*8))-1);
250
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
224
251
max_key_file_length=
225
252
mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
226
((uint64_t) 1 << (share->base.key_reflength*8))-1);
253
((ulonglong) 1 << (share->base.key_reflength*8))-1);
227
254
#if SIZEOF_OFF_T == 4
228
set_if_smaller(max_data_file_length, INT32_MAX);
229
set_if_smaller(max_key_file_length, INT32_MAX);
255
set_if_smaller(max_data_file_length, INT_MAX32);
256
set_if_smaller(max_key_file_length, INT_MAX32);
258
#if USE_RAID && SYSTEM_SIZEOF_OFF_T == 4
259
set_if_smaller(max_key_file_length, INT_MAX32);
260
if (!share->base.raid_type)
262
set_if_smaller(max_data_file_length, INT_MAX32);
266
set_if_smaller(max_data_file_length,
267
(ulonglong) share->base.raid_chunks << 31);
269
#elif !defined(USE_RAID)
231
270
if (share->base.raid_type)
233
errno=HA_ERR_UNSUPPORTED;
272
DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
273
my_errno=HA_ERR_UNSUPPORTED;
236
share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
237
share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
277
share->base.max_data_file_length=(my_off_t) max_data_file_length;
278
share->base.max_key_file_length=(my_off_t) max_key_file_length;
239
280
if (share->options & HA_OPTION_COMPRESS_RECORD)
240
281
share->base.max_key_length+=2; /* For safety */
242
283
/* Add space for node pointer */
243
284
share->base.max_key_length+= share->base.key_reflength;
245
if (!drizzled::memory::multi_malloc(false,
246
&share,sizeof(*share),
247
&share->state.rec_per_key_part,sizeof(long)*key_parts,
248
&share->keyinfo,keys*sizeof(MI_KEYDEF),
249
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
251
(key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
252
&share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
253
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
254
&share->unique_file_name,strlen(name_buff)+1,
255
&share->index_file_name,strlen(index_name)+1,
256
&share->data_file_name,strlen(data_name)+1,
257
&share->state.key_root,keys*sizeof(uint64_t),
258
&share->state.key_del,
259
(share->state.header.max_block_size_index*sizeof(uint64_t)),
286
if (!my_multi_malloc(MY_WME,
287
&share,sizeof(*share),
288
&share->state.rec_per_key_part,sizeof(long)*key_parts,
289
&share->keyinfo,keys*sizeof(MI_KEYDEF),
290
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
292
(key_parts+unique_key_parts+keys+uniques) *
295
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
296
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
297
&share->unique_file_name,strlen(name_buff)+1,
298
&share->index_file_name,strlen(index_name)+1,
299
&share->data_file_name,strlen(data_name)+1,
300
&share->state.key_root,keys*sizeof(my_off_t),
301
&share->state.key_del,
302
(share->state.header.max_block_size_index*sizeof(my_off_t)),
304
&share->key_root_lock,sizeof(rw_lock_t)*keys,
306
&share->mmap_lock,sizeof(rw_lock_t),
263
310
*share=share_buff;
264
memcpy(share->state.rec_per_key_part, rec_per_key_part,
265
sizeof(long)*key_parts);
266
memcpy(share->state.key_root, key_root,
267
sizeof(internal::my_off_t)*keys);
268
memcpy(share->state.key_del, key_del,
269
sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
270
strcpy(share->unique_file_name, name_buff);
311
memcpy((char*) share->state.rec_per_key_part,
312
(char*) rec_per_key_part, sizeof(long)*key_parts);
313
memcpy((char*) share->state.key_root,
314
(char*) key_root, sizeof(my_off_t)*keys);
315
memcpy((char*) share->state.key_del,
316
(char*) key_del, (sizeof(my_off_t) *
317
share->state.header.max_block_size_index));
318
strmov(share->unique_file_name, name_buff);
271
319
share->unique_name_length= strlen(name_buff);
272
strcpy(share->index_file_name, index_name);
273
strcpy(share->data_file_name, data_name);
320
strmov(share->index_file_name, index_name);
321
strmov(share->data_file_name, data_name);
275
share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
323
share->blocksize=min(IO_SIZE,myisam_block_size);
277
325
HA_KEYSEG *pos=share->keyparts;
278
326
for (i=0 ; i < keys ; i++)
300
350
if (!pos->language)
301
351
pos->charset=default_charset_info;
302
else if (!(pos->charset= get_charset(pos->language)))
352
else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
304
errno=HA_ERR_UNKNOWN_CHARSET;
354
my_errno=HA_ERR_UNKNOWN_CHARSET;
308
358
else if (pos->type == HA_KEYTYPE_BINARY)
309
359
pos->charset= &my_charset_bin;
361
if (share->keyinfo[i].flag & HA_SPATIAL)
364
uint sp_segs=SPDIMS*2;
365
share->keyinfo[i].seg=pos-sp_segs;
366
share->keyinfo[i].keysegs--;
368
my_errno=HA_ERR_UNSUPPORTED;
372
else if (share->keyinfo[i].flag & HA_FULLTEXT)
375
{ /* 4.0 compatibility code, to be removed in 5.0 */
376
share->keyinfo[i].seg=pos-FT_SEGS;
377
share->keyinfo[i].keysegs-=FT_SEGS;
382
share->keyinfo[i].seg=pos;
383
for (k=0; k < FT_SEGS; k++)
386
pos[0].language= pos[-1].language;
387
if (!(pos[0].charset= pos[-1].charset))
389
my_errno=HA_ERR_CRASHED;
395
if (!share->ft2_keyinfo.seg)
397
memcpy(& share->ft2_keyinfo, & share->keyinfo[i], sizeof(MI_KEYDEF));
398
share->ft2_keyinfo.keysegs=1;
399
share->ft2_keyinfo.flag=0;
400
share->ft2_keyinfo.keylength=
401
share->ft2_keyinfo.minlength=
402
share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
403
share->ft2_keyinfo.seg=pos-1;
404
share->ft2_keyinfo.end=pos;
405
setup_key_functions(& share->ft2_keyinfo);
311
408
setup_key_functions(share->keyinfo+i);
312
409
share->keyinfo[i].end=pos;
313
410
pos->type=HA_KEYTYPE_END; /* End */
389
490
share->base.margin_key_file_length=(share->base.max_key_file_length -
390
491
(keys ? MI_INDEX_BLOCK_MARGIN *
391
492
share->blocksize * keys : 0));
392
share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
493
share->blocksize=min(IO_SIZE,myisam_block_size);
393
494
share->data_file_type=STATIC_RECORD;
394
if (share->options & HA_OPTION_PACK_RECORD)
495
if (share->options & HA_OPTION_COMPRESS_RECORD)
497
share->data_file_type = COMPRESSED_RECORD;
498
share->options|= HA_OPTION_READ_ONLY_DATA;
500
if (_mi_read_pack_info(&info,
502
test(!(share->options &
503
(HA_OPTION_PACK_RECORD |
504
HA_OPTION_TEMP_COMPRESS_RECORD)))))
507
else if (share->options & HA_OPTION_PACK_RECORD)
395
508
share->data_file_type = DYNAMIC_RECORD;
509
my_afree(disk_cache);
398
510
mi_setup_functions(share);
399
share->is_log_table= false;
400
if (myisam_concurrent_insert)
511
share->is_log_table= FALSE;
513
thr_lock_init(&share->lock);
514
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
515
for (i=0; i<keys; i++)
516
VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
517
VOID(my_rwlock_init(&share->mmap_lock, NULL));
518
if (!thr_lock_inited)
520
/* Probably a single threaded program; Don't use concurrent inserts */
521
myisam_concurrent_insert=0;
523
else if (myisam_concurrent_insert)
402
525
share->concurrent_insert=
403
526
((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
404
527
HA_OPTION_COMPRESS_RECORD |
405
528
HA_OPTION_TEMP_COMPRESS_RECORD)) ||
406
(open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
529
(open_flags & HA_OPEN_TMP_TABLE) ||
407
531
if (share->concurrent_insert)
533
share->lock.get_status=mi_get_status;
534
share->lock.copy_status=mi_copy_status;
535
share->lock.update_status=mi_update_status;
536
share->lock.restore_status= mi_restore_status;
537
share->lock.check_status=mi_check_status;
542
Memory mapping can only be requested after initializing intern_lock.
544
if (open_flags & HA_OPEN_MMAP)
547
mi_extra(&info, HA_EXTRA_MMAP, 0);
415
552
share= old_info->s;
416
553
if (mode == O_RDWR && share->mode == O_RDONLY)
418
errno=EACCES; /* Can't open in write mode */
555
my_errno=EACCES; /* Can't open in write mode */
421
558
if (mi_open_datafile(&info, share, old_info->dfile))
427
564
/* alloc and set up private structure parts */
428
if (!drizzled::memory::multi_malloc(MY_WME,
429
&m_info,sizeof(MI_INFO),
430
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
431
&info.buff,(share->base.max_key_block_length*2+
432
share->base.max_key_length),
433
&info.lastkey,share->base.max_key_length*3+1,
434
&info.first_mbr_key, share->base.max_key_length,
435
&info.filename, identifier.getPath().length()+1,
436
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
565
if (!my_multi_malloc(MY_WME,
566
&m_info,sizeof(MI_INFO),
567
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
568
&info.buff,(share->base.max_key_block_length*2+
569
share->base.max_key_length),
570
&info.lastkey,share->base.max_key_length*3+1,
571
&info.first_mbr_key, share->base.max_key_length,
572
&info.filename,strlen(name)+1,
573
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
442
579
info.rtree_recursion_state= NULL;
444
strcpy(info.filename, identifier.getPath().c_str());
581
strmov(info.filename,name);
445
582
memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
446
583
info.lastkey2=info.lastkey+share->base.max_key_length;
477
616
share->temporary=share->delay_key_write=1;
478
617
share->write_flag=MYF(MY_NABP);
480
* The following two statements are commented out as a fix of
481
* bug https://bugs.launchpad.net/drizzle/+bug/387627
483
* UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
484
* The root cause of why this makes a difference hasn't
485
* been found, but this fixes things for now.
487
// share->w_locks++; // We don't have to update status
488
// share->tot_locks++;
618
share->w_locks++; /* We don't have to update status */
489
620
info.lock_type=F_WRLCK;
492
share->delay_key_write= 1;
622
if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
623
(share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
624
myisam_delay_key_write)
625
share->delay_key_write=1;
493
626
info.state= &share->state.state; /* Change global values by default */
627
pthread_mutex_unlock(&share->intern_lock);
495
629
/* Allocate buffer for one record */
497
/* prerequisites: memset(info, 0) && info->s=share; are met. */
498
if (!mi_alloc_rec_buff(&info, SIZE_MAX, &info.rec_buff))
631
/* prerequisites: bzero(info) && info->s=share; are met. */
632
if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
500
memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
634
bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
503
myisam_open_list.push_front(m_info);
638
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
640
m_info->open_list.data=(void*) m_info;
641
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
505
THR_LOCK_myisam.unlock();
643
pthread_mutex_unlock(&THR_LOCK_myisam);
644
if (myisam_log_file >= 0)
646
intern_filename(name_buff,share->index_file_name);
647
_myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
509
if (disk_cache != NULL)
511
save_errno=errno ? errno : HA_ERR_END_OF_FILE;
652
save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
512
653
if ((save_errno == HA_ERR_CRASHED) ||
513
654
(save_errno == HA_ERR_CRASHED_ON_USAGE) ||
514
655
(save_errno == HA_ERR_CRASHED_ON_REPAIR))
515
mi_report_error(save_errno, identifier.getPath().c_str());
656
mi_report_error(save_errno, name);
516
657
switch (errpos) {
518
free((unsigned char*) m_info);
659
my_free((uchar*) m_info,MYF(0));
519
660
/* fall through */
521
internal::my_close(info.dfile,MYF(0));
662
VOID(my_close(info.dfile,MYF(0)));
523
664
break; /* Don't remove open table */
524
665
/* fall through */
526
free((unsigned char*) share);
667
my_free((uchar*) share,MYF(0));
527
668
/* fall through */
671
VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
674
my_afree(disk_cache);
529
675
/* fall through */
531
internal::my_close(kfile,MYF(0));
677
VOID(my_close(kfile,MYF(0)));
532
678
/* fall through */
537
THR_LOCK_myisam.unlock();
683
pthread_mutex_unlock(&THR_LOCK_myisam);
543
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
689
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
546
uint32_t old_length= 0;
692
uint32 old_length= 0;
548
694
if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
550
unsigned char *newptr = *buf;
696
uchar *newptr = *buf;
552
698
/* to simplify initial init of info->rec_buf in mi_open and mi_extra */
553
if (length == SIZE_MAX)
699
if (length == (ulong) -1)
555
701
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
556
702
length= max(info->s->base.pack_reclength, info->s->max_pack_length);
558
704
length= info->s->base.pack_reclength;
559
length= max((uint32_t)length, info->s->base.max_key_length);
705
length= max(length, info->s->base.max_key_length);
560
706
/* Avoid unnecessary realloc */
561
707
if (newptr && length == old_length)