summaryrefslogtreecommitdiff
path: root/storage/maria/ma_delete.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/maria/ma_delete.c')
-rw-r--r--storage/maria/ma_delete.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 22ffb05af38..fa2ee166b7c 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -63,7 +63,7 @@ int maria_delete(MARIA_HA *info,const uchar *record)
if ((*share->compare_record)(info,record))
goto err; /* Error on read-check */
- if (_ma_mark_file_changed(info))
+ if (_ma_mark_file_changed(share))
goto err;
/* Ensure we don't change the autoincrement value */
@@ -134,17 +134,12 @@ err:
save_errno= HA_ERR_INTERNAL_ERROR; /* Should never happen */
mi_sizestore(lastpos, info->cur_row.lastpos);
- if (save_errno != HA_ERR_RECORD_CHANGED)
- {
- maria_print_error(share, HA_ERR_CRASHED);
- maria_mark_crashed(info); /* mark table crashed */
- }
- _ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
+ (void) _ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
- if (save_errno == HA_ERR_KEY_NOT_FOUND)
+ if (save_errno != HA_ERR_RECORD_CHANGED)
{
- maria_print_error(share, HA_ERR_CRASHED);
- my_errno=HA_ERR_CRASHED;
+ _ma_set_fatal_error(share, HA_ERR_CRASHED);
+ save_errno= HA_ERR_CRASHED;
}
DBUG_RETURN(my_errno= save_errno);
} /* maria_delete */
@@ -209,7 +204,7 @@ my_bool _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
if ((old_root=*root) == HA_OFFSET_ERROR)
{
- my_errno=HA_ERR_CRASHED;
+ _ma_set_fatal_error(info->s, HA_ERR_CRASHED);
DBUG_RETURN(1);
}
if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
@@ -344,7 +339,7 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
if (!(tmp_key_length=(*keyinfo->get_key)(&tmp_key, page_flag, nod_flag,
&kpos)))
{
- my_errno= HA_ERR_CRASHED;
+ _ma_set_fatal_error(share, HA_ERR_CRASHED);
DBUG_RETURN(-1);
}
root= _ma_row_pos_from_key(&tmp_key);
@@ -406,8 +401,9 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
{
if (!nod_flag)
{
+ /* This should newer happend */
DBUG_PRINT("error",("Didn't find key"));
- my_errno=HA_ERR_CRASHED; /* This should newer happend */
+ _ma_set_fatal_error(share, HA_ERR_CRASHED);
goto err;
}
save_flag=0;
@@ -571,6 +567,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
endpos= leaf_page->buff + leaf_length;
tmp_key.keyinfo= keyinfo;
tmp_key.data= keybuff;
+ next_buff= 0;
if (!(key_start= _ma_get_last_key(&tmp_key, leaf_page, endpos)))
DBUG_RETURN(-1);
@@ -597,9 +594,11 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
/* underflow writes "next_page" to disk */
ret_value= underflow(info, keyinfo, leaf_page, &next_page,
endpos);
- if (ret_value == 0 && leaf_page->size >
- share->max_index_block_size)
+ if (ret_value < 0)
+ goto err;
+ if (leaf_page->size > share->max_index_block_size)
{
+ DBUG_ASSERT(ret_value == 0);
ret_value= (_ma_split_page(info, key, leaf_page,
share->max_index_block_size,
(uchar*) 0, 0, 0,
@@ -632,6 +631,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
goto err;
}
my_afree(next_buff);
+ DBUG_ASSERT(leaf_page->size <= share->max_index_block_size);
DBUG_RETURN(ret_value);
}
@@ -709,10 +709,14 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
KEY_OP_DEBUG_LOG_ADD_2))
goto err;
+ DBUG_ASSERT(leaf_page->size <= share->max_index_block_size);
DBUG_RETURN(new_leaf_length <=
(info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
(uint) keyinfo->underflow_block_length));
err:
+ if (next_buff)
+ my_afree(next_buff);
+
DBUG_RETURN(-1);
} /* del */
@@ -731,9 +735,18 @@ err:
leaf_page is saved to disk
Caller must save anc_buff
+ For the algoritm to work, we have to ensure for packed keys that
+ key_length + (underflow_length + max_block_length + key_length) / 2
+ <= block_length.
+ From which follows that underflow_length <= block_length - key_length *3
+ For not packed keys we have:
+ (underflow_length + max_block_length + key_length) / 2 <= block_length
+ From which follows that underflow_length < block_length - key_length
+ This is ensured by setting of underflow_block_length.
+
@return
@retval 0 ok
- @retval 1 ok, but anc_buff did underflow
+ @retval 1 ok, but anc_page did underflow
@retval -1 error
*/
@@ -1153,7 +1166,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_kpointer(info,leaf_key.data + leaf_key.data_length +
leaf_key.ref_length, leaf_page->pos);
- /* Save key in anc_page */
+ /* Save parting key found by _ma_find_half_pos() in anc_page */
DBUG_DUMP("anc_buff", anc_buff, new_anc_length);
DBUG_DUMP_KEY("key_to_anc", &leaf_key);
anc_end_pos= anc_buff + new_anc_length;
@@ -1191,6 +1204,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
bmove(leaf_buff+p_length+t_length, half_pos, tmp_length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted);
new_leaf_length= tmp_length + t_length + p_length;
+ DBUG_ASSERT(new_leaf_length <= share->max_index_block_size);
leaf_page->size= new_leaf_length;
leaf_page->flag= page_flag;
@@ -1232,7 +1246,6 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/*
Log changes to next page
This contains original data with some suffix data deleted
-
*/
DBUG_ASSERT(new_buff_length <= buff_length);
if (_ma_log_suffix(&next_page, buff_length, new_buff_length))