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
/* Remove a row from a MyISAM table */
18
#include "myisam_priv.h"
19
#include <drizzled/internal/m_string.h>
18
#include "myisamdef.h"
20
19
#include <drizzled/util/test.h>
22
using namespace drizzled;
24
21
static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint32_t comp_flag,
25
unsigned char *key,uint32_t key_length,internal::my_off_t page,unsigned char *anc_buff);
22
unsigned char *key,uint32_t key_length,my_off_t page,unsigned char *anc_buff);
26
23
static int del(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,unsigned char *anc_buff,
27
internal::my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos,
28
internal::my_off_t next_block,unsigned char *ret_key);
24
my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos,
25
my_off_t next_block,unsigned char *ret_key);
29
26
static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *anc_buff,
30
internal::my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos);
27
my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos);
31
28
static uint32_t remove_key(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *keypos,
32
29
unsigned char *lastkey,unsigned char *page_end,
33
internal::my_off_t *next_block);
30
my_off_t *next_block);
34
31
static int _mi_ck_real_delete(register MI_INFO *info,MI_KEYDEF *keyinfo,
35
unsigned char *key, uint32_t key_length, internal::my_off_t *root);
32
unsigned char *key, uint32_t key_length, my_off_t *root);
38
35
int mi_delete(MI_INFO *info,const unsigned char *record)
47
44
/* Test if record is in datafile */
48
45
if (!(info->update & HA_STATE_AKTIV))
50
return(errno=HA_ERR_KEY_NOT_FOUND); /* No database read */
47
return(my_errno=HA_ERR_KEY_NOT_FOUND); /* No database read */
52
49
if (share->options & HA_OPTION_READ_ONLY_DATA)
51
return(my_errno=EACCES);
56
53
if (_mi_readinfo(info,F_WRLCK,1))
58
55
if (info->s->calc_checksum)
59
56
info->checksum=(*info->s->calc_checksum)(info,record);
60
57
if ((*share->compare_record)(info,record))
91
88
mi_sizestore(lastpos,info->lastpos);
92
89
_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
90
if (info->invalidator != 0)
92
(*info->invalidator)(info->filename);
97
99
mi_sizestore(lastpos,info->lastpos);
98
100
if (save_errno != HA_ERR_RECORD_CHANGED)
126
128
static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
127
unsigned char *key, uint32_t key_length, internal::my_off_t *root)
129
unsigned char *key, uint32_t key_length, my_off_t *root)
130
132
uint32_t nod_flag;
131
internal::my_off_t old_root;
132
134
unsigned char *root_buff;
134
136
if ((old_root=*root) == HA_OFFSET_ERROR)
136
138
mi_print_error(info->s, HA_ERR_CRASHED);
137
return(errno=HA_ERR_CRASHED);
139
return(my_errno=HA_ERR_CRASHED);
139
if (!(root_buff= (unsigned char*) malloc(keyinfo->block_length+
141
if (!(root_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
140
142
MI_MAX_KEY_BUFF*2)))
142
return(errno=ENOMEM);
144
return(my_errno=ENOMEM);
144
146
if (!_mi_fetch_keypage(info,keyinfo,old_root,DFLT_INIT_HITS,root_buff,0))
186
188
static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
187
189
uint32_t comp_flag, unsigned char *key, uint32_t key_length,
188
internal::my_off_t page, unsigned char *anc_buff)
190
my_off_t page, unsigned char *anc_buff)
190
192
int flag,ret_value,save_flag;
191
193
uint32_t length,nod_flag,search_key_length;
193
195
unsigned char *leaf_buff,*keypos;
194
internal::my_off_t leaf_page= 0, next_block;
196
my_off_t leaf_page= 0, next_block;
195
197
unsigned char lastkey[MI_MAX_KEY_BUFF];
197
199
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
209
211
leaf_page=_mi_kpos(nod_flag,keypos);
210
if (!(leaf_buff= (unsigned char*) malloc(keyinfo->block_length+
212
if (!(leaf_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
211
213
MI_MAX_KEY_BUFF*2)))
216
218
if (!_mi_fetch_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff,0))
268
270
ret_value=_mi_insert(info,keyinfo,key,anc_buff,keypos,lastkey,
269
(unsigned char*) 0,(unsigned char*) 0,(internal::my_off_t) 0,(bool) 0);
271
(unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,(bool) 0);
272
274
if (ret_value == 0 && mi_getint(anc_buff) > keyinfo->block_length)
288
290
/* Remove a key that has a page-reference */
290
292
static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *key,
291
unsigned char *anc_buff, internal::my_off_t leaf_page, unsigned char *leaf_buff,
293
unsigned char *anc_buff, my_off_t leaf_page, unsigned char *leaf_buff,
292
294
unsigned char *keypos, /* Pos to where deleted key was */
293
internal::my_off_t next_block,
294
296
unsigned char *ret_key) /* key before keypos in anc_buff */
296
298
int ret_value,length;
297
299
uint32_t a_length,nod_flag,tmp;
298
internal::my_off_t next_page;
299
301
unsigned char keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
300
302
MYISAM_SHARE *share=info->s;
301
303
MI_KEY_PARAM s_temp;
308
310
if ((nod_flag=mi_test_if_nod(leaf_buff)))
310
312
next_page= _mi_kpos(nod_flag,endpos);
311
if (!(next_buff= (unsigned char*) malloc(keyinfo->block_length+
313
if (!(next_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
312
314
MI_MAX_KEY_BUFF*2)))
314
316
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
336
338
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
337
(unsigned char*) 0,(unsigned char*) 0,(internal::my_off_t) 0,0);
339
(unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,0);
340
342
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
345
my_afree((unsigned char*) next_buff);
344
346
return(ret_value);
364
366
prev_key, prev_key,
365
367
keybuff,&s_temp);
367
internal::bmove_upp((unsigned char*) endpos+length,(unsigned char*) endpos,(uint) (endpos-keypos));
369
bmove_upp((unsigned char*) endpos+length,(unsigned char*) endpos,(uint) (endpos-keypos));
369
memmove(keypos,keypos-length, (int) (endpos-keypos)+length);
371
memcpy(keypos,keypos-length, (int) (endpos-keypos)+length);
370
372
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
371
373
/* Save pointer to next leaf */
372
374
if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key))
387
389
static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
388
390
unsigned char *anc_buff,
389
internal::my_off_t leaf_page,/* Ancestor page and underflow page */
391
my_off_t leaf_page,/* Ancestor page and underflow page */
390
392
unsigned char *leaf_buff,
391
393
unsigned char *keypos) /* Position to pos after key */
394
396
uint32_t length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
395
397
key_reflength,key_length;
396
internal::my_off_t next_page;
397
399
unsigned char anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
398
400
*buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key,
434
436
buff_length=mi_getint(buff);
436
438
/* find keys to make a big key-page */
437
memmove(next_keypos - key_reflength, buff + 2, key_reflength);
439
memcpy(next_keypos - key_reflength, buff + 2, key_reflength);
438
440
if (!_mi_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length)
439
441
|| !_mi_get_last_key(info,keyinfo,leaf_buff,leaf_key,
440
442
leaf_buff+leaf_length,&length))
448
450
length=buff_length-p_length;
449
451
endpos=buff+length+leaf_length+t_length;
450
452
/* buff will always be larger than before !*/
451
internal::bmove_upp((unsigned char*) endpos, (unsigned char*) buff+buff_length,length);
453
bmove_upp((unsigned char*) endpos, (unsigned char*) buff+buff_length,length);
452
454
memcpy(buff, leaf_buff, leaf_length);
453
455
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
454
456
buff_length=(uint) (endpos-buff);
493
495
prev_key, prev_key,
494
496
leaf_key, &s_temp);
495
497
if (t_length >= 0)
496
internal::bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,
498
bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,
497
499
(uint) (endpos-keypos));
499
memmove(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
501
memcpy(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
500
502
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
501
503
mi_putint(anc_buff,(anc_length+=t_length),key_reflength);
503
505
/* Store key first in new page */
505
memmove(buff + 2, half_pos - nod_flag, nod_flag);
507
memcpy(buff + 2, half_pos - nod_flag, nod_flag);
506
508
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))
508
510
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (unsigned char*) 0,
510
512
leaf_key, &s_temp);
511
513
/* t_length will always be > 0 for a new page !*/
512
514
length=(uint) ((buff+mi_getint(buff))-half_pos);
513
memmove(buff + p_length + t_length, half_pos, length);
515
memcpy(buff + p_length + t_length, half_pos, length);
514
516
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
515
517
mi_putint(buff,length+t_length+p_length,nod_flag);
533
535
endpos=buff+buff_length;
535
537
/* find keys to make a big key-page */
536
memmove(next_keypos - key_reflength, leaf_buff+2, key_reflength);
538
memcpy(next_keypos - key_reflength, leaf_buff+2, key_reflength);
537
539
next_keypos=keypos;
538
540
if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos,
549
551
prev_key, prev_key,
550
552
anc_key, &s_temp);
551
553
if (t_length >= 0)
552
memmove(endpos+t_length,leaf_buff+p_length, leaf_length-p_length);
554
memcpy(endpos+t_length,leaf_buff+p_length, leaf_length-p_length);
553
555
else /* We gained space */
554
memmove(endpos, leaf_buff+((int) p_length-t_length),
555
leaf_length - p_length + t_length);
556
memcpy(endpos, leaf_buff+((int) p_length-t_length),
557
leaf_length - p_length + t_length);
557
559
(*keyinfo->store_key)(keyinfo,endpos,&s_temp);
558
560
buff_length=buff_length+leaf_length-p_length+t_length;
592
594
anc_pos, anc_pos,
593
595
leaf_key,&s_temp);
594
596
if (t_length > 0)
595
internal::bmove_upp((unsigned char*) temp_pos+t_length,(unsigned char*) temp_pos,
597
bmove_upp((unsigned char*) temp_pos+t_length,(unsigned char*) temp_pos,
596
598
(uint) (temp_pos-keypos));
598
memmove(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
600
memcpy(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
599
601
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
600
602
mi_putint(anc_buff,(anc_length+=t_length),key_reflength);
602
604
/* Store first key on new page */
604
memmove(leaf_buff+2, half_pos - nod_flag, nod_flag);
606
memcpy(leaf_buff+2, half_pos - nod_flag, nod_flag);
605
607
if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)))
607
609
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (unsigned char*) 0,
608
610
(unsigned char*) 0, (unsigned char*) 0, leaf_key, &s_temp);
609
611
length=(uint) ((buff+buff_length)-half_pos);
610
memmove(leaf_buff + p_length + t_length, half_pos, length);
612
memcpy(leaf_buff + p_length + t_length, half_pos, length);
611
613
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
612
614
mi_putint(leaf_buff,length+t_length+p_length,nod_flag);
613
615
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
668
670
if (next_length > prev_length)
670
672
/* We have to copy data from the current key to the next key */
671
internal::bmove_upp(keypos, (lastkey+next_length),
673
bmove_upp(keypos, (lastkey+next_length),
672
674
(next_length-prev_length));
673
675
keypos-=(next_length-prev_length)+prev_pack_length;
674
676
store_key_length(keypos,prev_length);
715
717
if (next_length >= prev_length)
716
718
{ /* Key after is based on deleted key */
717
719
uint32_t pack_length,tmp;
718
internal::bmove_upp(keypos, (lastkey+next_length),
719
tmp=(next_length-prev_length));
720
bmove_upp(keypos, (lastkey+next_length),
721
tmp=(next_length-prev_length));
720
722
rest_length+=tmp;
721
723
pack_length= prev_length ? get_pack_length(rest_length): 0;
722
724
keypos-=tmp+pack_length+prev_pack_length;