summaryrefslogtreecommitdiff
path: root/storage/maria/ma_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/maria/ma_write.c')
-rw-r--r--storage/maria/ma_write.c216
1 files changed, 129 insertions, 87 deletions
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 24768b36c89..a4fe5506c8e 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -24,33 +24,52 @@
/* Functions declared in this file */
static int w_search(MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- uint comp_flag, uchar *key,
- uint key_length, my_off_t pos, uchar *father_buff,
- uchar *father_keypos, my_off_t father_page,
+ uint comp_flag, byte *key,
+ uint key_length, my_off_t pos, byte *father_buff,
+ byte *father_keypos, my_off_t father_page,
my_bool insert_last);
-static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *key,
- uchar *curr_buff,uchar *father_buff,
- uchar *father_keypos,my_off_t father_page);
-static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
- uchar **after_key);
-int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,uchar *key,
+static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,byte *key,
+ byte *curr_buff,byte *father_buff,
+ byte *father_keypos,my_off_t father_page);
+static byte *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint *return_key_length,
+ byte **after_key);
+int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,byte *key,
uint key_length);
-int _ma_ck_write_btree(register MARIA_HA *info, uint keynr,uchar *key,
+int _ma_ck_write_btree(register MARIA_HA *info, uint keynr,byte *key,
uint key_length);
- /* Write new record to database */
+
+MARIA_RECORD_POS _ma_write_init_default(MARIA_HA *info,
+ const byte *record
+ __attribute__((unused)))
+{
+ return ((info->s->state.dellink != HA_OFFSET_ERROR &&
+ !info->append_insert_at_end) ?
+ info->s->state.dellink :
+ info->state->data_file_length);
+}
+
+my_bool _ma_write_abort_default(MARIA_HA *info __attribute__((unused)))
+{
+ return 0;
+}
+
+
+/* Write new record to a table */
int maria_write(MARIA_HA *info, byte *record)
{
MARIA_SHARE *share=info->s;
uint i;
int save_errno;
- my_off_t filepos;
- uchar *buff;
+ MARIA_RECORD_POS filepos;
+ byte *buff;
my_bool lock_tree= share->concurrent_insert;
+ my_bool fatal_error;
DBUG_ENTER("maria_write");
- DBUG_PRINT("enter",("isam: %d data: %d",info->s->kfile,info->dfile));
+ DBUG_PRINT("enter",("index_file: %d data_file: %d",
+ info->s->kfile,info->dfile));
DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_usage",
maria_print_error(info->s, HA_ERR_CRASHED);
@@ -62,10 +81,6 @@ int maria_write(MARIA_HA *info, byte *record)
if (_ma_readinfo(info,F_WRLCK,1))
DBUG_RETURN(my_errno);
dont_break(); /* Dont allow SIGHUP or SIGINT */
- filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
- !info->append_insert_at_end) ?
- share->state.dellink :
- info->state->data_file_length);
if (share->base.reloc == (ha_rows) 1 &&
share->base.records == (ha_rows) 1 &&
@@ -86,14 +101,26 @@ int maria_write(MARIA_HA *info, byte *record)
for (i=0 ; i < share->state.header.uniques ; i++)
{
if (_ma_check_unique(info,share->uniqueinfo+i,record,
- _ma_unique_hash(share->uniqueinfo+i,record),
- HA_OFFSET_ERROR))
+ _ma_unique_hash(share->uniqueinfo+i,record),
+ HA_OFFSET_ERROR))
goto err2;
}
- /* Write all keys to indextree */
+ if ((info->opt_flag & OPT_NO_ROWS))
+ filepos= HA_OFFSET_ERROR;
+ else
+ {
+ /*
+ This may either calculate a record or, or write the record and return
+ the record id
+ */
+ if ((filepos= (*share->write_record_init)(info, record)) ==
+ HA_OFFSET_ERROR)
+ goto err2;
+ }
- buff=info->lastkey2;
+ /* Write all keys to indextree */
+ buff= info->lastkey2;
for (i=0 ; i < share->base.keys ; i++)
{
if (maria_is_key_active(share->state.key_map, i))
@@ -136,13 +163,13 @@ int maria_write(MARIA_HA *info, byte *record)
rw_unlock(&share->key_root_lock[i]);
}
}
- if (share->calc_checksum)
- info->checksum=(*share->calc_checksum)(info,record);
- if (!(info->opt_flag & OPT_NO_ROWS))
+ if (share->calc_write_checksum)
+ info->cur_row.checksum= (*share->calc_write_checksum)(info,record);
+ if (filepos != HA_OFFSET_ERROR)
{
if ((*share->write_record)(info,record))
goto err;
- info->state->checksum+=info->checksum;
+ info->state->checksum+= info->cur_row.checksum;
}
if (share->base.auto_key)
set_if_bigger(info->s->state.auto_increment,
@@ -150,7 +177,7 @@ int maria_write(MARIA_HA *info, byte *record)
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
HA_STATE_ROW_CHANGED);
info->state->records++;
- info->lastpos=filepos;
+ info->cur_row.lastpos= filepos;
VOID(_ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
if (info->invalidator != 0)
{
@@ -162,8 +189,10 @@ int maria_write(MARIA_HA *info, byte *record)
DBUG_RETURN(0);
err:
- save_errno=my_errno;
- if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
+ save_errno= my_errno;
+ fatal_error= 0;
+ if (my_errno == HA_ERR_FOUND_DUPP_KEY ||
+ my_errno == HA_ERR_RECORD_FILE_FULL ||
my_errno == HA_ERR_NULL_IN_SPATIAL)
{
if (info->bulk_insert)
@@ -207,14 +236,21 @@ err:
}
}
else
+ fatal_error= 1;
+
+ if ((*share->write_record_abort)(info))
+ fatal_error= 1;
+ if (fatal_error)
{
maria_print_error(info->s, HA_ERR_CRASHED);
maria_mark_crashed(info);
}
+
info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED);
my_errno=save_errno;
err2:
save_errno=my_errno;
+ DBUG_PRINT("error", ("got error: %d", save_errno));
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(my_errno=save_errno);
@@ -223,7 +259,7 @@ err2:
/* Write one key to btree */
-int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
+int _ma_ck_write(MARIA_HA *info, uint keynr, byte *key, uint key_length)
{
DBUG_ENTER("_ma_ck_write");
@@ -242,7 +278,7 @@ int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
* Normal insert code *
**********************************************************************/
-int _ma_ck_write_btree(register MARIA_HA *info, uint keynr, uchar *key,
+int _ma_ck_write_btree(register MARIA_HA *info, uint keynr, byte *key,
uint key_length)
{
int error;
@@ -275,15 +311,17 @@ int _ma_ck_write_btree(register MARIA_HA *info, uint keynr, uchar *key,
DBUG_RETURN(error);
} /* _ma_ck_write_btree */
+
int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length, my_off_t *root, uint comp_flag)
+ byte *key, uint key_length, my_off_t *root,
+ uint comp_flag)
{
int error;
DBUG_ENTER("_ma_ck_real_write_btree");
/* key_length parameter is used only if comp_flag is SEARCH_FIND */
if (*root == HA_OFFSET_ERROR ||
(error=w_search(info, keyinfo, comp_flag, key, key_length,
- *root, (uchar *) 0, (uchar*) 0,
+ *root, (byte*) 0, (byte*) 0,
(my_off_t) 0, 1)) > 0)
error= _ma_enlarge_root(info,keyinfo,key,root);
DBUG_RETURN(error);
@@ -292,7 +330,7 @@ int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* Make a new root with key as only pointer */
-int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
+int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
my_off_t *root)
{
uint t_length,nod_flag;
@@ -302,11 +340,11 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
nod_flag= (*root != HA_OFFSET_ERROR) ? share->base.key_reflength : 0;
_ma_kpointer(info,info->buff+2,*root); /* if nod */
- t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar*) 0,
- (uchar*) 0, (uchar*) 0, key,&s_temp);
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(byte*) 0,
+ (byte*) 0, (byte*) 0, key,&s_temp);
maria_putint(info->buff,t_length+2+nod_flag,nod_flag);
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
- info->buff_used=info->page_changed=1; /* info->buff is used */
+ info->keybuff_used=info->page_changed=1; /* info->buff is used */
if ((*root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
DBUG_RETURN(-1);
@@ -322,21 +360,21 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
*/
static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uint comp_flag, uchar *key, uint key_length, my_off_t page,
- uchar *father_buff, uchar *father_keypos,
+ uint comp_flag, byte *key, uint key_length, my_off_t page,
+ byte *father_buff, byte *father_keypos,
my_off_t father_page, my_bool insert_last)
{
int error,flag;
uint nod_flag, search_key_length;
- uchar *temp_buff,*keypos;
- uchar keybuff[HA_MAX_KEY_BUFF];
+ byte *temp_buff,*keypos;
+ byte keybuff[HA_MAX_KEY_BUFF];
my_bool was_last_key;
- my_off_t next_page, dupp_key_pos;
+ my_off_t next_page, dup_key_pos;
DBUG_ENTER("w_search");
DBUG_PRINT("enter",("page: %ld",page));
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
- if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
+ if (!(temp_buff= (byte*) my_alloca((uint) keyinfo->block_length+
HA_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_ma_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
@@ -351,9 +389,9 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* get position to record with duplicated key */
tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff);
if (tmp_key_length)
- dupp_key_pos= _ma_dpos(info,0,keybuff+tmp_key_length);
+ dup_key_pos= _ma_dpos(info,0,keybuff+tmp_key_length);
else
- dupp_key_pos= HA_OFFSET_ERROR;
+ dup_key_pos= HA_OFFSET_ERROR;
if (keyinfo->flag & HA_FULLTEXT)
{
@@ -373,7 +411,7 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
else
{
/* popular word. two-level tree. going down */
- my_off_t root=dupp_key_pos;
+ my_off_t root=dup_key_pos;
keyinfo=&info->s->ft2_keyinfo;
get_key_full_length_rdonly(off, key);
key+=off;
@@ -392,7 +430,7 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
}
else /* not HA_FULLTEXT, normal HA_NOSAME key */
{
- info->dupp_key_pos= dupp_key_pos;
+ info->dup_key_pos= dup_key_pos;
my_afree((byte*) temp_buff);
my_errno=HA_ERR_FOUND_DUPP_KEY;
DBUG_RETURN(-1);
@@ -447,25 +485,25 @@ err:
*/
int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *anc_buff, uchar *key_pos, uchar *key_buff,
- uchar *father_buff, uchar *father_key_pos, my_off_t father_page,
+ byte *key, byte *anc_buff, byte *key_pos, byte *key_buff,
+ byte *father_buff, byte *father_key_pos, my_off_t father_page,
my_bool insert_last)
{
uint a_length,nod_flag;
int t_length;
- uchar *endpos, *prev_key;
+ byte *endpos, *prev_key;
MARIA_KEY_PARAM s_temp;
DBUG_ENTER("_ma_insert");
- DBUG_PRINT("enter",("key_pos: %lx",key_pos));
+ DBUG_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,
USE_WHOLE_KEY););
nod_flag=_ma_test_if_nod(anc_buff);
a_length=maria_getint(anc_buff);
endpos= anc_buff+ a_length;
- prev_key=(key_pos == anc_buff+2+nod_flag ? (uchar*) 0 : key_buff);
+ prev_key=(key_pos == anc_buff+2+nod_flag ? (byte*) 0 : key_buff);
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
- (key_pos == endpos ? (uchar*) 0 : key_pos),
+ (key_pos == endpos ? (byte*) 0 : key_pos),
prev_key, prev_key,
key,&s_temp);
#ifndef DBUG_OFF
@@ -478,7 +516,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
{
DBUG_PRINT("test",("t_length: %d ref_len: %d",
t_length,s_temp.ref_length));
- DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: %lx",
+ DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: 0x%lx",
s_temp.n_ref_length,s_temp.n_length,s_temp.key));
}
#endif
@@ -517,19 +555,20 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
Let's consider converting.
We'll compare 'key' and the first key at anc_buff
*/
- uchar *a=key, *b=anc_buff+2+nod_flag;
+ byte *a=key, *b=anc_buff+2+nod_flag;
uint alen, blen, ft2len=info->s->ft2_keyinfo.keylength;
/* the very first key on the page is always unpacked */
DBUG_ASSERT((*b & 128) == 0);
#if HA_FT_MAXLEN >= 127
blen= mi_uint2korr(b); b+=2;
#else
- blen= *b++;
+ blen= *(uchar*) b++;
#endif
get_key_length(alen,a);
DBUG_ASSERT(info->ft1_to_ft2==0);
if (alen == blen &&
- ha_compare_text(keyinfo->seg->charset, a, alen, b, blen, 0, 0)==0)
+ ha_compare_text(keyinfo->seg->charset, (uchar*) a, alen,
+ (uchar*) b, blen, 0, 0) == 0)
{
/* yup. converting */
info->ft1_to_ft2=(DYNAMIC_ARRAY *)
@@ -570,11 +609,11 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* split a full page in two and assign emerging item to key */
int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *buff, uchar *key_buff,
+ byte *key, byte *buff, byte *key_buff,
my_bool insert_last_key)
{
uint length,a_length,key_ref_length,t_length,nod_flag,key_length;
- uchar *key_pos,*pos, *after_key;
+ byte *key_pos,*pos, *after_key;
my_off_t new_pos;
MARIA_KEY_PARAM s_temp;
DBUG_ENTER("maria_split_page");
@@ -582,7 +621,7 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (info->s->keyinfo+info->lastinx == keyinfo)
info->page_changed=1; /* Info->buff is used */
- info->buff_used=1;
+ info->keybuff_used=1;
nod_flag=_ma_test_if_nod(buff);
key_ref_length=2+nod_flag;
if (insert_last_key)
@@ -614,8 +653,8 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&key_pos,key_buff))
DBUG_RETURN(-1);
- t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar *) 0,
- (uchar*) 0, (uchar*) 0,
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(byte *) 0,
+ (byte*) 0, (byte*) 0,
key_buff, &s_temp);
length=(uint) ((buff+a_length)-key_pos);
memcpy((byte*) info->buff+key_ref_length+t_length,(byte*) key_pos,
@@ -638,12 +677,12 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
after_key will contain the position to where the next key starts
*/
-uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
- uchar **after_key)
+byte *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint *return_key_length,
+ byte **after_key)
{
uint keys,length,key_ref_length;
- uchar *end,*lastpos;
+ byte *end,*lastpos;
DBUG_ENTER("_ma_find_half_pos");
key_ref_length=2+nod_flag;
@@ -672,24 +711,25 @@ uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
} while (page < end);
*return_key_length=length;
*after_key=page;
- DBUG_PRINT("exit",("returns: %lx page: %lx half: %lx",lastpos,page,end));
+ DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx half: 0x%lx",
+ lastpos, page, end));
DBUG_RETURN(lastpos);
} /* _ma_find_half_pos */
- /*
- Split buffer at last key
- Returns pointer to the start of the key before the last key
- key will contain the last key
- */
+/*
+ Split buffer at last key
+ Returns pointer to the start of the key before the last key
+ key will contain the last key
+*/
-static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
- uchar **after_key)
+static byte *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint *return_key_length,
+ byte **after_key)
{
uint keys,length,last_length,key_ref_length;
- uchar *end,*lastpos,*prevpos;
- uchar key_buff[HA_MAX_KEY_BUFF];
+ byte *end,*lastpos,*prevpos;
+ byte key_buff[HA_MAX_KEY_BUFF];
DBUG_ENTER("_ma_find_last_pos");
key_ref_length=2;
@@ -727,7 +767,8 @@ static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
}
*return_key_length=last_length;
*after_key=lastpos;
- DBUG_PRINT("exit",("returns: %lx page: %lx end: %lx",prevpos,page,end));
+ DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx end: 0x%lx",
+ prevpos, page, end));
DBUG_RETURN(prevpos);
} /* _ma_find_last_pos */
@@ -736,14 +777,14 @@ static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
/* returns 0 if balance was done */
static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *curr_buff, uchar *father_buff,
- uchar *father_key_pos, my_off_t father_page)
+ byte *key, byte *curr_buff, byte *father_buff,
+ byte *father_key_pos, my_off_t father_page)
{
my_bool right;
uint k_length,father_length,father_keylength,nod_flag,curr_keylength,
right_length,left_length,new_right_length,new_left_length,extra_length,
length,keys;
- uchar *pos,*buff,*extra_buff;
+ byte *pos,*buff,*extra_buff;
my_off_t next_page,new_pos;
byte tmp_part_key[HA_MAX_KEY_BUFF];
DBUG_ENTER("_ma_balance_page");
@@ -880,7 +921,8 @@ typedef struct {
uint keynr;
} bulk_insert_param;
-int _ma_ck_write_tree(register MARIA_HA *info, uint keynr, uchar *key,
+
+int _ma_ck_write_tree(register MARIA_HA *info, uint keynr, byte *key,
uint key_length)
{
int error;
@@ -896,22 +938,22 @@ int _ma_ck_write_tree(register MARIA_HA *info, uint keynr, uchar *key,
/* typeof(_ma_keys_compare)=qsort_cmp2 */
-static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
+static int keys_compare(bulk_insert_param *param, byte *key1, byte *key2)
{
uint not_used[2];
return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg,
- key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
+ (uchar*) key1, (uchar*) key2, USE_WHOLE_KEY, SEARCH_SAME,
not_used);
}
-static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param)
+static int keys_free(byte *key, TREE_FREE mode, bulk_insert_param *param)
{
/*
Probably I can use info->lastkey here, but I'm not sure,
and to be safe I'd better use local lastkey.
*/
- uchar lastkey[HA_MAX_KEY_BUFF];
+ byte lastkey[HA_MAX_KEY_BUFF];
uint keylen;
MARIA_KEYDEF *keyinfo;