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