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;
86
85
info->state->records--;
88
87
mi_sizestore(lastpos,info->lastpos);
89
_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
88
myisam_log_command(MI_LOG_DELETE,info,(uchar*) lastpos,sizeof(lastpos),0);
89
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
90
90
if (info->invalidator != 0)
92
92
(*info->invalidator)(info->filename);
98
98
save_errno=my_errno;
99
99
mi_sizestore(lastpos,info->lastpos);
100
myisam_log_command(MI_LOG_DELETE,info,(uchar*) lastpos, sizeof(lastpos),0);
100
101
if (save_errno != HA_ERR_RECORD_CHANGED)
102
103
mi_print_error(info->s, HA_ERR_CRASHED);
103
104
mi_mark_crashed(info); /* mark table crashed */
105
_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
106
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
106
107
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
107
108
my_errno=save_errno;
108
109
if (save_errno == HA_ERR_KEY_NOT_FOUND)
118
119
/* Remove a key from the btree index */
120
int _mi_ck_delete(register MI_INFO *info, uint32_t keynr, unsigned char *key,
121
int _mi_ck_delete(register MI_INFO *info, uint keynr, uchar *key,
123
124
return _mi_ck_real_delete(info, info->s->keyinfo+keynr, key, key_length,
124
125
&info->s->state.key_root[keynr]);
128
129
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)
130
uchar *key, uint key_length, my_off_t *root)
133
134
my_off_t old_root;
134
unsigned char *root_buff;
136
137
if ((old_root=*root) == HA_OFFSET_ERROR)
138
139
mi_print_error(info->s, HA_ERR_CRASHED);
139
140
return(my_errno=HA_ERR_CRASHED);
141
if (!(root_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
142
if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
142
143
MI_MAX_KEY_BUFF*2)))
144
145
return(my_errno=ENOMEM);
188
189
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)
190
uint comp_flag, uchar *key, uint key_length,
191
my_off_t page, uchar *anc_buff)
192
193
int flag,ret_value,save_flag;
193
uint32_t length,nod_flag,search_key_length;
195
unsigned char *leaf_buff,*keypos;
194
uint length,nod_flag,search_key_length;
196
uchar *leaf_buff,*keypos;
196
197
my_off_t leaf_page= 0, next_block;
197
unsigned char lastkey[MI_MAX_KEY_BUFF];
198
uchar lastkey[MI_MAX_KEY_BUFF];
199
200
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
200
201
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
270
271
ret_value=_mi_insert(info,keyinfo,key,anc_buff,keypos,lastkey,
271
(unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,(bool) 0);
272
(uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0);
274
275
if (ret_value == 0 && mi_getint(anc_buff) > keyinfo->block_length)
279
280
if (save_flag && ret_value != 1)
280
281
ret_value|=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
281
my_afree((unsigned char*) leaf_buff);
282
my_afree((uchar*) leaf_buff);
282
283
return(ret_value);
285
my_afree((unsigned char*) leaf_buff);
286
my_afree((uchar*) leaf_buff);
290
291
/* 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 */
293
static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
294
uchar *anc_buff, my_off_t leaf_page, uchar *leaf_buff,
295
uchar *keypos, /* Pos to where deleted key was */
295
296
my_off_t next_block,
296
unsigned char *ret_key) /* key before keypos in anc_buff */
297
uchar *ret_key) /* key before keypos in anc_buff */
298
299
int ret_value,length;
299
uint32_t a_length,nod_flag,tmp;
300
uint a_length,nod_flag,tmp;
300
301
my_off_t next_page;
301
unsigned char keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
302
uchar keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
302
303
MYISAM_SHARE *share=info->s;
303
304
MI_KEY_PARAM s_temp;
310
311
if ((nod_flag=mi_test_if_nod(leaf_buff)))
312
313
next_page= _mi_kpos(nod_flag,endpos);
313
if (!(next_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
314
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
314
315
MI_MAX_KEY_BUFF*2)))
316
317
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
338
339
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
339
(unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,0);
340
(uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
342
343
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
345
my_afree((unsigned char*) next_buff);
346
my_afree((uchar*) next_buff);
346
347
return(ret_value);
362
363
prev_key=(keypos == anc_buff+2+share->base.key_reflength ?
364
365
length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
365
keypos == endpos ? (unsigned char*) 0 : keypos,
366
keypos == endpos ? (uchar*) 0 : keypos,
366
367
prev_key, prev_key,
367
368
keybuff,&s_temp);
369
bmove_upp((unsigned char*) endpos+length,(unsigned char*) endpos,(uint) (endpos-keypos));
370
bmove_upp((uchar*) endpos+length,(uchar*) endpos,(uint) (endpos-keypos));
371
372
memcpy(keypos,keypos-length, (int) (endpos-keypos)+length);
372
373
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
387
388
/* Balances adjacent pages if underflow occours */
389
390
static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
390
unsigned char *anc_buff,
391
392
my_off_t leaf_page,/* Ancestor page and underflow page */
392
unsigned char *leaf_buff,
393
unsigned char *keypos) /* Position to pos after key */
394
uchar *keypos) /* Position to pos after key */
396
uint32_t length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
397
uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
397
398
key_reflength,key_length;
398
399
my_off_t next_page;
399
unsigned char anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
400
uchar anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
400
401
*buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key,
402
403
MI_KEY_PARAM s_temp;
445
446
/* merge pages and put parting key from anc_buff between */
446
prev_key=(leaf_length == p_length ? (unsigned char*) 0 : leaf_key);
447
prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
447
448
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,buff+p_length,
448
449
prev_key, prev_key,
449
450
anc_key, &s_temp);
450
451
length=buff_length-p_length;
451
452
endpos=buff+length+leaf_length+t_length;
452
453
/* buff will always be larger than before !*/
453
bmove_upp((unsigned char*) endpos, (unsigned char*) buff+buff_length,length);
454
bmove_upp((uchar*) endpos, (uchar*) buff+buff_length,length);
454
455
memcpy(buff, leaf_buff, leaf_length);
455
456
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
456
457
buff_length=(uint) (endpos-buff);
488
489
half_pos=after_key;
489
490
_mi_kpointer(info,leaf_key+key_length,next_page);
490
491
/* Save key in anc_buff */
491
prev_key=(keypos == anc_buff+2+key_reflength ? (unsigned char*) 0 : anc_key),
492
prev_key=(keypos == anc_buff+2+key_reflength ? (uchar*) 0 : anc_key),
492
493
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
493
(keypos == endpos ? (unsigned char*) 0 :
494
(keypos == endpos ? (uchar*) 0 :
495
496
prev_key, prev_key,
496
497
leaf_key, &s_temp);
497
498
if (t_length >= 0)
498
bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,
499
bmove_upp((uchar*) endpos+t_length,(uchar*) endpos,
499
500
(uint) (endpos-keypos));
501
502
memcpy(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
507
508
memcpy(buff + 2, half_pos - nod_flag, nod_flag);
508
509
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,
511
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
512
(uchar*) 0, (uchar *) 0,
512
513
leaf_key, &s_temp);
513
514
/* t_length will always be > 0 for a new page !*/
514
515
length=(uint) ((buff+mi_getint(buff))-half_pos);
546
547
/* merge pages and put parting key from anc_buff between */
547
prev_key=(leaf_length == p_length ? (unsigned char*) 0 : leaf_key);
548
prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
548
549
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
549
550
(leaf_length == p_length ?
550
(unsigned char*) 0 : leaf_buff+p_length),
551
(uchar*) 0 : leaf_buff+p_length),
551
552
prev_key, prev_key,
552
553
anc_key, &s_temp);
553
554
if (t_length >= 0)
590
591
temp_pos=anc_buff+anc_length;
591
592
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
592
keypos == temp_pos ? (unsigned char*) 0
593
keypos == temp_pos ? (uchar*) 0
594
595
anc_pos, anc_pos,
595
596
leaf_key,&s_temp);
596
597
if (t_length > 0)
597
bmove_upp((unsigned char*) temp_pos+t_length,(unsigned char*) temp_pos,
598
bmove_upp((uchar*) temp_pos+t_length,(uchar*) temp_pos,
598
599
(uint) (temp_pos-keypos));
600
601
memcpy(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
606
607
memcpy(leaf_buff+2, half_pos - nod_flag, nod_flag);
607
608
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);
610
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (uchar*) 0,
611
(uchar*) 0, (uchar*) 0, leaf_key, &s_temp);
611
612
length=(uint) ((buff+buff_length)-half_pos);
612
613
memcpy(leaf_buff + p_length + t_length, half_pos, length);
613
614
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
632
633
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 */
636
static uint remove_key(MI_KEYDEF *keyinfo, uint nod_flag,
637
uchar *keypos, /* Where key starts */
638
uchar *lastkey, /* key to be removed */
639
uchar *page_end, /* End of page */
639
640
my_off_t *next_block) /* ptr to next block */
642
unsigned char *start;
645
646
if (!(keyinfo->flag &
664
665
if (keyinfo->flag & HA_BINARY_PACK_KEY)
666
unsigned char *old_key=start;
667
uint32_t next_length,prev_length,prev_pack_length;
667
uchar *old_key=start;
668
uint next_length,prev_length,prev_pack_length;
668
669
get_key_length(next_length,keypos);
669
670
get_key_pack_length(prev_length,prev_pack_length,old_key);
670
671
if (next_length > prev_length)
683
684
if ((keyinfo->seg->flag & HA_PACK_KEY) && *keypos & 128)
685
686
/* Next key is packed against the current one */
686
uint32_t next_length,prev_length,prev_pack_length,lastkey_length,
687
uint next_length,prev_length,prev_pack_length,lastkey_length,
688
689
if (keyinfo->seg[0].length >= 127)