diff options
author | Sergei Golubchik <serg@mariadb.org> | 2019-02-17 16:06:02 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2019-02-21 14:57:10 +0100 |
commit | 81ecc2b2b52cc97fab0f2cd7d9a02cea89eec14b (patch) | |
tree | 588438956505589d64a95905c3b11cf7604b4514 /sql | |
parent | 8ad23ff49834775b07397ebd8d2840c203aab59a (diff) | |
download | mariadb-git-81ecc2b2b52cc97fab0f2cd7d9a02cea89eec14b.tar.gz |
store string lengths in frm in 1-3 bytes
Diffstat (limited to 'sql')
-rw-r--r-- | sql/table.cc | 78 | ||||
-rw-r--r-- | sql/table.h | 6 | ||||
-rw-r--r-- | sql/unireg.cc | 47 |
3 files changed, 65 insertions, 66 deletions
diff --git a/sql/table.cc b/sql/table.cc index 73002506cd1..16569b8097f 100644 --- a/sql/table.cc +++ b/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; } diff --git a/sql/table.h b/sql/table.h index a49b1f29529..9b182fc08e0 100644 --- a/sql/table.h +++ b/sql/table.h @@ -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; diff --git a/sql/unireg.cc b/sql/unireg.cc index d70a73b89c7..7a20c14c8d4 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -72,16 +72,21 @@ static uchar *extra2_write_len(uchar *pos, size_t len) return pos; } -static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, - const LEX_CSTRING &str) +static uchar* extra2_write_str(uchar *pos, const LEX_CSTRING &str) { - *pos++ = type; 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; + return extra2_write_str(pos, str); +} + +static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type, const LEX_CUSTRING &str) { return extra2_write(pos, type, *reinterpret_cast<const LEX_CSTRING*>(&str)); @@ -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) -{ - 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) +static size_t extra2_str_size(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)); |