Skip to content

Commit 6435aeb

Browse files
committed
Fixed "frame size..larger thane 16384" error in MyISAM
Fixed by using my_alloc() and by using 'needed allocation size' instead of maxium possible.
1 parent 317f099 commit 6435aeb

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

storage/myisam/mi_open.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -913,12 +913,16 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo)
913913

914914
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
915915
{
916-
uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
917-
uchar *ptr=buff;
916+
uchar *buff, *ptr;
918917
uint i, keys= (uint) state->header.keys,
919-
key_blocks=state->header.max_block_size_index;
918+
key_blocks=state->header.max_block_size_index,
919+
key_parts= mi_uint2korr(state->header.key_parts);
920+
int res;
920921
DBUG_ENTER("mi_state_info_write");
921922

923+
buff= my_alloca(MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE(keys, key_parts));
924+
925+
ptr= buff;
922926
memcpy(ptr, &state->header, sizeof(state->header));
923927
ptr+=sizeof(state->header);
924928

@@ -952,7 +956,6 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
952956
}
953957
if (pWrite & 2) /* From isamchk */
954958
{
955-
uint key_parts= mi_uint2korr(state->header.key_parts);
956959
mi_int4store(ptr,state->sec_index_changed); ptr +=4;
957960
mi_int4store(ptr,state->sec_index_used); ptr +=4;
958961
mi_int4store(ptr,state->version); ptr +=4;
@@ -968,10 +971,13 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
968971
}
969972

970973
if (pWrite & 1)
971-
DBUG_RETURN(mysql_file_pwrite(file, buff, (size_t) (ptr-buff), 0L,
972-
MYF(MY_NABP | MY_THREADSAFE)) != 0);
973-
DBUG_RETURN(mysql_file_write(file, buff, (size_t) (ptr-buff),
974-
MYF(MY_NABP)) != 0);
974+
res= mysql_file_pwrite(file, buff, (size_t) (ptr-buff), 0L,
975+
MYF(MY_NABP | MY_THREADSAFE)) != 0;
976+
else
977+
res= mysql_file_write(file, buff, (size_t) (ptr-buff),
978+
MYF(MY_NABP)) != 0;
979+
my_afree(buff);
980+
DBUG_RETURN(res);
975981
}
976982

977983

@@ -1040,20 +1046,24 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
10401046

10411047
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
10421048
{
1043-
uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
1049+
uchar *buff= my_alloca(state->state_length);
10441050

10451051
if (!myisam_single_user)
10461052
{
10471053
if (pRead)
10481054
{
10491055
if (mysql_file_pread(file, buff, state->state_length, 0L, MYF(MY_NABP)))
1050-
return 1;
1056+
goto err;
10511057
}
10521058
else if (mysql_file_read(file, buff, state->state_length, MYF(MY_NABP)))
1053-
return 1;
1059+
goto err;
10541060
mi_state_info_read(buff, state);
10551061
}
1062+
my_afree(buff);
10561063
return 0;
1064+
err:
1065+
my_afree(buff);
1066+
return 1;
10571067
}
10581068

10591069

storage/myisam/myisamdef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ typedef struct st_mi_state_info
9797
#define MI_STATE_KEY_SIZE 8U
9898
#define MI_STATE_KEYBLOCK_SIZE 8U
9999
#define MI_STATE_KEYSEG_SIZE 4U
100-
#define MI_STATE_EXTRA_SIZE ((MI_MAX_KEY+MI_MAX_KEY_BLOCK_SIZE)*MI_STATE_KEY_SIZE + MI_MAX_KEY*HA_MAX_KEY_SEG*MI_STATE_KEYSEG_SIZE)
100+
#define MI_STATE_EXTRA_SIZE(K,P) (((K)+MI_MAX_KEY_BLOCK_SIZE)*MI_STATE_KEY_SIZE + (P)*MI_STATE_KEYSEG_SIZE)
101+
101102
#define MI_KEYDEF_SIZE (2+ 5*2)
102103
#define MI_UNIQUEDEF_SIZE (2+1+1)
103104
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)

0 commit comments

Comments
 (0)