store string lengths in frm in 1-3 bytes
This commit is contained in:
parent
8ad23ff498
commit
81ecc2b2b5
78
sql/table.cc
78
sql/table.cc
@ -57,7 +57,7 @@ struct extra2_fields
|
||||
Lex_ident engine;
|
||||
LEX_CUSTRING gis;
|
||||
LEX_CUSTRING field_flags;
|
||||
const uchar *system_period;
|
||||
LEX_CUSTRING system_period;
|
||||
LEX_CUSTRING application_period;
|
||||
};
|
||||
|
||||
@ -1363,12 +1363,30 @@ void TABLE::find_constraint_correlated_indexes()
|
||||
}
|
||||
|
||||
|
||||
bool TABLE_SHARE::init_period_from_extra2(period_info_t &period,
|
||||
const uchar *data)
|
||||
bool TABLE_SHARE::init_period_from_extra2(period_info_t *period,
|
||||
const uchar *data, const uchar *end)
|
||||
{
|
||||
period.start_fieldno= read_frm_fieldno(data);
|
||||
period.end_fieldno= read_frm_fieldno(data + frm_fieldno_size);
|
||||
return period.start_fieldno >= fields || period.end_fieldno >= fields;
|
||||
if (data + 2*frm_fieldno_size > end)
|
||||
return 1;
|
||||
period->start_fieldno= read_frm_fieldno(data);
|
||||
period->end_fieldno= read_frm_fieldno(data + frm_fieldno_size);
|
||||
return period->start_fieldno >= fields || period->end_fieldno >= fields;
|
||||
}
|
||||
|
||||
|
||||
static size_t extra2_read_len(const uchar **extra2, const uchar *extra2_end)
|
||||
{
|
||||
size_t length= *(*extra2)++;
|
||||
if (length)
|
||||
return length;
|
||||
|
||||
if ((*extra2) + 2 >= extra2_end)
|
||||
return 0;
|
||||
length= uint2korr(*extra2);
|
||||
(*extra2)+= 2;
|
||||
if (length < 256 || *extra2 + length > extra2_end)
|
||||
return 0;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
@ -1386,18 +1404,9 @@ bool read_extra2(const uchar *frm_image, size_t len, extra2_fields *fields)
|
||||
const uchar *e2end= extra2 + len;
|
||||
while (extra2 + 3 <= e2end)
|
||||
{
|
||||
uchar type= *extra2++;
|
||||
size_t length= *extra2++;
|
||||
extra2_frm_value_type type= (extra2_frm_value_type)*extra2++;
|
||||
size_t length= extra2_read_len(&extra2, e2end);
|
||||
if (!length)
|
||||
{
|
||||
if (extra2 + 2 >= e2end)
|
||||
DBUG_RETURN(true);
|
||||
length= uint2korr(extra2);
|
||||
extra2+= 2;
|
||||
if (length < 256)
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (extra2 + length > e2end)
|
||||
DBUG_RETURN(true);
|
||||
switch (type) {
|
||||
case EXTRA2_TABLEDEF_VERSION:
|
||||
@ -1428,9 +1437,10 @@ bool read_extra2(const uchar *frm_image, size_t len, extra2_fields *fields)
|
||||
fields->gis.length= length;
|
||||
break;
|
||||
case EXTRA2_PERIOD_FOR_SYSTEM_TIME:
|
||||
if (fields->system_period || length != 2 * frm_fieldno_size)
|
||||
if (fields->system_period.str || length != 2 * frm_fieldno_size)
|
||||
DBUG_RETURN(true);
|
||||
fields->system_period = extra2;
|
||||
fields->system_period.str = extra2;
|
||||
fields->system_period.length= length;
|
||||
break;
|
||||
case EXTRA2_FIELD_FLAGS:
|
||||
if (fields->field_flags.str)
|
||||
@ -2006,7 +2016,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
|
||||
/* Set system versioning information. */
|
||||
vers.name= Lex_ident(STRING_WITH_LEN("SYSTEM_TIME"));
|
||||
if (extra2.system_period == NULL)
|
||||
if (extra2.system_period.str == NULL)
|
||||
{
|
||||
versioned= VERS_UNDEFINED;
|
||||
vers.start_fieldno= 0;
|
||||
@ -2015,7 +2025,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("info", ("Setting system versioning informations"));
|
||||
if (init_period_from_extra2(vers, extra2.system_period))
|
||||
if (init_period_from_extra2(&vers, extra2.system_period.str,
|
||||
extra2.system_period.str + extra2.system_period.length))
|
||||
goto err;
|
||||
DBUG_PRINT("info", ("Columns with system versioning: [%d, %d]",
|
||||
vers.start_fieldno, vers.end_fieldno));
|
||||
@ -2026,25 +2037,18 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
|
||||
if (extra2.application_period.str)
|
||||
{
|
||||
const uchar *name_pos= extra2.application_period.str + frm_ident_len_size;
|
||||
period.name.length= uint2korr(extra2.application_period.str);
|
||||
period.name.str= strmake_root(&mem_root,
|
||||
(char*)name_pos,
|
||||
period.name.length);
|
||||
const uchar *pos= extra2.application_period.str;
|
||||
const uchar *end= pos + extra2.application_period.length;
|
||||
period.name.length= extra2_read_len(&pos, end);
|
||||
period.name.str= strmake_root(&mem_root, (char*)pos, period.name.length);
|
||||
pos+= period.name.length;
|
||||
|
||||
const uchar *constr_pos= name_pos + period.name.length + frm_ident_len_size;
|
||||
period.constr_name.length= uint2korr(name_pos + period.name.length);
|
||||
period.constr_name.str= strmake_root(&mem_root,
|
||||
(char*)constr_pos,
|
||||
period.constr_name.length= extra2_read_len(&pos, end);
|
||||
period.constr_name.str= strmake_root(&mem_root, (char*)pos,
|
||||
period.constr_name.length);
|
||||
pos+= period.constr_name.length;
|
||||
|
||||
const uchar *field_pos= constr_pos + period.constr_name.length;
|
||||
if (init_period_from_extra2(period, field_pos))
|
||||
goto err;
|
||||
|
||||
if (period.name.length + period.constr_name.length
|
||||
+ 2 * frm_ident_len_size + 2 * frm_fieldno_size
|
||||
!= extra2.application_period.length)
|
||||
if (init_period_from_extra2(&period, pos, end))
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -789,7 +789,8 @@ struct TABLE_SHARE
|
||||
period_info_t vers;
|
||||
period_info_t period;
|
||||
|
||||
bool init_period_from_extra2(period_info_t &period, const uchar *data);
|
||||
bool init_period_from_extra2(period_info_t *period, const uchar *data,
|
||||
const uchar *end);
|
||||
|
||||
Field *vers_start_field()
|
||||
{
|
||||
@ -1788,9 +1789,6 @@ static inline uint16 read_frm_fieldno(const uchar *data)
|
||||
static inline void store_frm_fieldno(const uchar *data, uint16 fieldno)
|
||||
{ int2store(data, fieldno); }
|
||||
|
||||
/** number of bytes used by identifier length in frm */
|
||||
constexpr uint frm_ident_len_size= 2;
|
||||
|
||||
class select_unit;
|
||||
class TMP_TABLE_PARAM;
|
||||
|
||||
|
@ -72,13 +72,18 @@ static uchar *extra2_write_len(uchar *pos, size_t len)
|
||||
return pos;
|
||||
}
|
||||
|
||||
static uchar* extra2_write_str(uchar *pos, const LEX_CSTRING &str)
|
||||
{
|
||||
pos= extra2_write_len(pos, str.length);
|
||||
memcpy(pos, str.str, str.length);
|
||||
return pos + str.length;
|
||||
}
|
||||
|
||||
static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type,
|
||||
const LEX_CSTRING &str)
|
||||
{
|
||||
*pos++ = type;
|
||||
pos= extra2_write_len(pos, str.length);
|
||||
memcpy(pos, str.str, str.length);
|
||||
return pos + str.length;
|
||||
return extra2_write_str(pos, str);
|
||||
}
|
||||
|
||||
static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type,
|
||||
@ -142,17 +147,9 @@ bool has_extra2_field_flags(List<Create_field> &create_fields)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
uchar* store_str(uchar *buf, const Lex_ident &str)
|
||||
static size_t extra2_str_size(size_t len)
|
||||
{
|
||||
int2store(buf, str.length);
|
||||
memcpy(buf + frm_ident_len_size, str.str, str.length);
|
||||
return buf + str.length + frm_ident_len_size;
|
||||
}
|
||||
|
||||
static size_t extra2_size_needed(size_t len)
|
||||
{
|
||||
return 1 + (len > 255 ? 3 : 1) + len;
|
||||
return (len > 255 ? 3 : 1) + len;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,9 +180,9 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table,
|
||||
uint options_len;
|
||||
uint gis_extra2_len= 0;
|
||||
size_t period_info_len= create_info->period_info.name
|
||||
? create_info->period_info.name.length
|
||||
+ create_info->period_info.constr->name.length
|
||||
+ 2 * frm_ident_len_size + 2 * frm_fieldno_size
|
||||
? extra2_str_size(create_info->period_info.name.length)
|
||||
+ extra2_str_size(create_info->period_info.constr->name.length)
|
||||
+ 2 * frm_fieldno_size
|
||||
: 0;
|
||||
uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE];
|
||||
const partition_info *part_info= IF_PARTITIONING(thd->work_part_info, 0);
|
||||
@ -283,30 +280,30 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table,
|
||||
prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info);
|
||||
|
||||
/* one byte for a type, one or three for a length */
|
||||
size_t extra2_size= extra2_size_needed(create_info->tabledef_version.length);
|
||||
size_t extra2_size= 1 + extra2_str_size(create_info->tabledef_version.length);
|
||||
if (options_len)
|
||||
extra2_size+= extra2_size_needed(options_len);
|
||||
extra2_size+= 1 + extra2_str_size(options_len);
|
||||
|
||||
if (part_info)
|
||||
extra2_size+= extra2_size_needed(hton_name(part_info->default_engine_type)->length);
|
||||
extra2_size+= 1 + extra2_str_size(hton_name(part_info->default_engine_type)->length);
|
||||
|
||||
if (gis_extra2_len)
|
||||
extra2_size+= extra2_size_needed(gis_extra2_len);
|
||||
extra2_size+= 1 + extra2_str_size(gis_extra2_len);
|
||||
|
||||
if (create_info->versioned())
|
||||
{
|
||||
extra2_size+= extra2_size_needed(2 * frm_fieldno_size);
|
||||
extra2_size+= 1 + extra2_str_size(2 * frm_fieldno_size);
|
||||
}
|
||||
|
||||
if (create_info->period_info.name)
|
||||
{
|
||||
extra2_size+= extra2_size_needed(period_info_len);
|
||||
extra2_size+= 1 + extra2_str_size(period_info_len);
|
||||
}
|
||||
|
||||
bool has_extra2_field_flags_= has_extra2_field_flags(create_fields);
|
||||
if (has_extra2_field_flags_)
|
||||
{
|
||||
extra2_size+= extra2_size_needed(create_fields.elements);
|
||||
extra2_size+= 1 + extra2_str_size(create_fields.elements);
|
||||
}
|
||||
|
||||
key_buff_length= uint4korr(fileinfo+47);
|
||||
@ -369,8 +366,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table,
|
||||
{
|
||||
*pos++= EXTRA2_APPLICATION_TIME_PERIOD;
|
||||
pos= extra2_write_len(pos, period_info_len);
|
||||
pos= store_str(pos, create_info->period_info.name);
|
||||
pos= store_str(pos, create_info->period_info.constr->name);
|
||||
pos= extra2_write_str(pos, create_info->period_info.name);
|
||||
pos= extra2_write_str(pos, create_info->period_info.constr->name);
|
||||
|
||||
store_frm_fieldno(pos, get_fieldno_by_name(create_info, create_fields,
|
||||
create_info->period_info.period.start));
|
||||
|
Loading…
x
Reference in New Issue
Block a user