diff options
-rw-r--r-- | sql/field.cc | 5 | ||||
-rw-r--r-- | sql/field.h | 6 | ||||
-rw-r--r-- | sql/ha_archive.cc | 22 |
3 files changed, 33 insertions, 0 deletions
diff --git a/sql/field.cc b/sql/field.cc index 2c484bb0979..8395b8c6145 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6412,6 +6412,11 @@ void Field_varstring::sql_type(String &res) const } +uint Field_varstring::data_length(const char *from) +{ + return length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); +} + /* Functions to create a packed row. Here the number of length bytes are depending on the given max_length diff --git a/sql/field.h b/sql/field.h index 3306c4123db..2ad564fc753 100644 --- a/sql/field.h +++ b/sql/field.h @@ -144,6 +144,11 @@ public: table, which is located on disk). */ virtual uint32 pack_length_in_rec() const { return pack_length(); } + + /* + data_length() return the "real size" of the data in memory. + */ + virtual uint32 data_length(const char *from) { return pack_length(); } virtual uint32 sort_length() const { return pack_length(); } virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset_fields() {} @@ -1102,6 +1107,7 @@ public: int key_cmp(const byte *str, uint length); uint packed_col_length(const char *to, uint length); uint max_packed_col_length(uint max_length); + uint data_length(const char *from); uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } bool has_charset(void) const diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc index 3885defb4d5..0fb0bc9f791 100644 --- a/sql/ha_archive.cc +++ b/sql/ha_archive.cc @@ -710,6 +710,28 @@ int ha_archive::write_row(byte *buf) if (init_archive_writer()) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + /* + Varchar structures are constant in size but are not cleaned up request + to request. The following sets all unused space to null to improve + compression. + */ + for (Field **field=table->field ; *field ; field++) + { + DBUG_PRINT("archive",("Pack is %d\n", (*field)->pack_length())); + DBUG_PRINT("archive",("MyPack is %d\n", (*field)->data_length((char*) buf + (*field)->offset()))); + if ((*field)->real_type() == MYSQL_TYPE_VARCHAR) + { + uint actual_length= (*field)->data_length((char*) buf + (*field)->offset()); + uint offset= (*field)->offset() + actual_length + + (actual_length > 255 ? 2 : 1); + DBUG_PRINT("archive",("Offset is %d -> %d\n", actual_length, offset)); + /* + if ((*field)->pack_length() + (*field)->offset() != offset) + bzero(buf + offset, (size_t)((*field)->pack_length() + (actual_length > 255 ? 2 : 1) - (*field)->data_length)); + */ + } + } + share->rows_recorded++; rc= real_write_row(buf, share->archive_write); pthread_mutex_unlock(&share->mutex); |