16
16
/* Remove a row from a MyISAM table */
18
18
#include "myisamdef.h"
19
#include <drizzled/util/test.h>
21
static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint32_t comp_flag,
22
unsigned char *key,uint32_t key_length,my_off_t page,unsigned char *anc_buff);
23
static int del(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,unsigned char *anc_buff,
24
my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos,
25
my_off_t next_block,unsigned char *ret_key);
26
static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *anc_buff,
27
my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos);
28
static uint32_t remove_key(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *keypos,
29
unsigned char *lastkey,unsigned char *page_end,
20
static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint comp_flag,
21
uchar *key,uint key_length,my_off_t page,uchar *anc_buff);
22
static int del(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,uchar *anc_buff,
23
my_off_t leaf_page,uchar *leaf_buff,uchar *keypos,
24
my_off_t next_block,uchar *ret_key);
25
static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *anc_buff,
26
my_off_t leaf_page,uchar *leaf_buff,uchar *keypos);
27
static uint remove_key(MI_KEYDEF *keyinfo,uint nod_flag,uchar *keypos,
28
uchar *lastkey,uchar *page_end,
30
29
my_off_t *next_block);
31
30
static int _mi_ck_real_delete(register MI_INFO *info,MI_KEYDEF *keyinfo,
32
unsigned char *key, uint32_t key_length, my_off_t *root);
35
int mi_delete(MI_INFO *info,const unsigned char *record)
31
uchar *key, uint key_length, my_off_t *root);
34
int mi_delete(MI_INFO *info,const uchar *record)
38
unsigned char *old_key;
102
101
mi_print_error(info->s, HA_ERR_CRASHED);
103
102
mi_mark_crashed(info); /* mark table crashed */
105
_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
104
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
106
105
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
107
106
my_errno=save_errno;
108
107
if (save_errno == HA_ERR_KEY_NOT_FOUND)
118
117
/* Remove a key from the btree index */
120
int _mi_ck_delete(register MI_INFO *info, uint32_t keynr, unsigned char *key,
119
int _mi_ck_delete(register MI_INFO *info, uint keynr, uchar *key,
123
122
return _mi_ck_real_delete(info, info->s->keyinfo+keynr, key, key_length,
124
123
&info->s->state.key_root[keynr]);
128
127
static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
129
unsigned char *key, uint32_t key_length, my_off_t *root)
128
uchar *key, uint key_length, my_off_t *root)
133
132
my_off_t old_root;
134
unsigned char *root_buff;
136
135
if ((old_root=*root) == HA_OFFSET_ERROR)
138
137
mi_print_error(info->s, HA_ERR_CRASHED);
139
138
return(my_errno=HA_ERR_CRASHED);
141
if (!(root_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
140
if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
142
141
MI_MAX_KEY_BUFF*2)))
144
143
return(my_errno=ENOMEM);
188
187
static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
189
uint32_t comp_flag, unsigned char *key, uint32_t key_length,
190
my_off_t page, unsigned char *anc_buff)
188
uint comp_flag, uchar *key, uint key_length,
189
my_off_t page, uchar *anc_buff)
192
191
int flag,ret_value,save_flag;
193
uint32_t length,nod_flag,search_key_length;
192
uint length,nod_flag,search_key_length;
195
unsigned char *leaf_buff,*keypos;
194
uchar *leaf_buff,*keypos;
196
195
my_off_t leaf_page= 0, next_block;
197
unsigned char lastkey[MI_MAX_KEY_BUFF];
196
uchar lastkey[MI_MAX_KEY_BUFF];
199
198
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
200
199
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
270
269
ret_value=_mi_insert(info,keyinfo,key,anc_buff,keypos,lastkey,
271
(unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,(bool) 0);
270
(uchar*) 0,(uchar*) 0,(my_off_t) 0,(bool) 0);
274
273
if (ret_value == 0 && mi_getint(anc_buff) > keyinfo->block_length)
279
278
if (save_flag && ret_value != 1)
280
279
ret_value|=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
281
my_afree((unsigned char*) leaf_buff);
280
my_afree((uchar*) leaf_buff);
282
281
return(ret_value);
285
my_afree((unsigned char*) leaf_buff);
284
my_afree((uchar*) leaf_buff);
290
289
/* Remove a key that has a page-reference */
292
static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *key,
293
unsigned char *anc_buff, my_off_t leaf_page, unsigned char *leaf_buff,
294
unsigned char *keypos, /* Pos to where deleted key was */
291
static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
292
uchar *anc_buff, my_off_t leaf_page, uchar *leaf_buff,
293
uchar *keypos, /* Pos to where deleted key was */
295
294
my_off_t next_block,
296
unsigned char *ret_key) /* key before keypos in anc_buff */
295
uchar *ret_key) /* key before keypos in anc_buff */
298
297
int ret_value,length;
299
uint32_t a_length,nod_flag,tmp;
298
uint a_length,nod_flag,tmp;
300
299
my_off_t next_page;
301
unsigned char keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
300
uchar keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
302
301
MYISAM_SHARE *share=info->s;
303
302
MI_KEY_PARAM s_temp;
310
309
if ((nod_flag=mi_test_if_nod(leaf_buff)))
312
311
next_page= _mi_kpos(nod_flag,endpos);
313
if (!(next_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
312
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
314
313
MI_MAX_KEY_BUFF*2)))
316
315
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
338
337
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
339
(unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,0);
338
(uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
342
341
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
345
my_afree((unsigned char*) next_buff);
344
my_afree((uchar*) next_buff);
346
345
return(ret_value);
362
361
prev_key=(keypos == anc_buff+2+share->base.key_reflength ?
364
363
length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
365
keypos == endpos ? (unsigned char*) 0 : keypos,
364
keypos == endpos ? (uchar*) 0 : keypos,
366
365
prev_key, prev_key,
367
366
keybuff,&s_temp);
369
bmove_upp((unsigned char*) endpos+length,(unsigned char*) endpos,(uint) (endpos-keypos));
368
bmove_upp((uchar*) endpos+length,(uchar*) endpos,(uint) (endpos-keypos));
371
370
memcpy(keypos,keypos-length, (int) (endpos-keypos)+length);
372
371
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
387
386
/* Balances adjacent pages if underflow occours */
389
388
static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
390
unsigned char *anc_buff,
391
390
my_off_t leaf_page,/* Ancestor page and underflow page */
392
unsigned char *leaf_buff,
393
unsigned char *keypos) /* Position to pos after key */
392
uchar *keypos) /* Position to pos after key */
396
uint32_t length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
395
uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
397
396
key_reflength,key_length;
398
397
my_off_t next_page;
399
unsigned char anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
398
uchar anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
400
399
*buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key,
402
401
MI_KEY_PARAM s_temp;
445
444
/* merge pages and put parting key from anc_buff between */
446
prev_key=(leaf_length == p_length ? (unsigned char*) 0 : leaf_key);
445
prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
447
446
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,buff+p_length,
448
447
prev_key, prev_key,
449
448
anc_key, &s_temp);
450
449
length=buff_length-p_length;
451
450
endpos=buff+length+leaf_length+t_length;
452
451
/* buff will always be larger than before !*/
453
bmove_upp((unsigned char*) endpos, (unsigned char*) buff+buff_length,length);
452
bmove_upp((uchar*) endpos, (uchar*) buff+buff_length,length);
454
453
memcpy(buff, leaf_buff, leaf_length);
455
454
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
456
455
buff_length=(uint) (endpos-buff);
488
487
half_pos=after_key;
489
488
_mi_kpointer(info,leaf_key+key_length,next_page);
490
489
/* Save key in anc_buff */
491
prev_key=(keypos == anc_buff+2+key_reflength ? (unsigned char*) 0 : anc_key),
490
prev_key=(keypos == anc_buff+2+key_reflength ? (uchar*) 0 : anc_key),
492
491
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
493
(keypos == endpos ? (unsigned char*) 0 :
492
(keypos == endpos ? (uchar*) 0 :
495
494
prev_key, prev_key,
496
495
leaf_key, &s_temp);
497
496
if (t_length >= 0)
498
bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,
497
bmove_upp((uchar*) endpos+t_length,(uchar*) endpos,
499
498
(uint) (endpos-keypos));
501
500
memcpy(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
507
506
memcpy(buff + 2, half_pos - nod_flag, nod_flag);
508
507
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))
510
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (unsigned char*) 0,
511
(unsigned char*) 0, (unsigned char *) 0,
509
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
510
(uchar*) 0, (uchar *) 0,
512
511
leaf_key, &s_temp);
513
512
/* t_length will always be > 0 for a new page !*/
514
513
length=(uint) ((buff+mi_getint(buff))-half_pos);
546
545
/* merge pages and put parting key from anc_buff between */
547
prev_key=(leaf_length == p_length ? (unsigned char*) 0 : leaf_key);
546
prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
548
547
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
549
548
(leaf_length == p_length ?
550
(unsigned char*) 0 : leaf_buff+p_length),
549
(uchar*) 0 : leaf_buff+p_length),
551
550
prev_key, prev_key,
552
551
anc_key, &s_temp);
553
552
if (t_length >= 0)
590
589
temp_pos=anc_buff+anc_length;
591
590
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
592
keypos == temp_pos ? (unsigned char*) 0
591
keypos == temp_pos ? (uchar*) 0
594
593
anc_pos, anc_pos,
595
594
leaf_key,&s_temp);
596
595
if (t_length > 0)
597
bmove_upp((unsigned char*) temp_pos+t_length,(unsigned char*) temp_pos,
596
bmove_upp((uchar*) temp_pos+t_length,(uchar*) temp_pos,
598
597
(uint) (temp_pos-keypos));
600
599
memcpy(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
606
605
memcpy(leaf_buff+2, half_pos - nod_flag, nod_flag);
607
606
if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)))
609
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (unsigned char*) 0,
610
(unsigned char*) 0, (unsigned char*) 0, leaf_key, &s_temp);
608
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (uchar*) 0,
609
(uchar*) 0, (uchar*) 0, leaf_key, &s_temp);
611
610
length=(uint) ((buff+buff_length)-half_pos);
612
611
memcpy(leaf_buff + p_length + t_length, half_pos, length);
613
612
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
632
631
returns how many chars was removed or 0 on error
635
static uint32_t remove_key(MI_KEYDEF *keyinfo, uint32_t nod_flag,
636
unsigned char *keypos, /* Where key starts */
637
unsigned char *lastkey, /* key to be removed */
638
unsigned char *page_end, /* End of page */
634
static uint remove_key(MI_KEYDEF *keyinfo, uint nod_flag,
635
uchar *keypos, /* Where key starts */
636
uchar *lastkey, /* key to be removed */
637
uchar *page_end, /* End of page */
639
638
my_off_t *next_block) /* ptr to next block */
642
unsigned char *start;
645
644
if (!(keyinfo->flag &
664
663
if (keyinfo->flag & HA_BINARY_PACK_KEY)
666
unsigned char *old_key=start;
667
uint32_t next_length,prev_length,prev_pack_length;
665
uchar *old_key=start;
666
uint next_length,prev_length,prev_pack_length;
668
667
get_key_length(next_length,keypos);
669
668
get_key_pack_length(prev_length,prev_pack_length,old_key);
670
669
if (next_length > prev_length)
683
682
if ((keyinfo->seg->flag & HA_PACK_KEY) && *keypos & 128)
685
684
/* Next key is packed against the current one */
686
uint32_t next_length,prev_length,prev_pack_length,lastkey_length,
685
uint next_length,prev_length,prev_pack_length,lastkey_length,
688
687
if (keyinfo->seg[0].length >= 127)