mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Fix for bug#20648 We introduce a new field method for knowing "real size", and we now in archive null unused bits of a row to null before writing.
sql/field.cc: data_length for field needs to be calculated directly. sql/field.h: The new method data_length() returns the "real" length of the field. sql/ha_archive.cc: Before a write_row() archive nulls space beyond the size of the row in varchars to make sure that compression only sees NULL.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user