Commit c55f24cd authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23162 Improve Protocol performance for numeric data

An alternative implementation (replacing the one based on repertoire).

This implementation makes Field send itself to Protocol_text using
data type specific Protocol methods rather than field->val_str()
followed by protocol_text->store_str().

As now Field sends itself in the same way to all protocol types
(e.g. Protocol_binary, Protocol_text, Protocol_local),
the method Field::send_binary() was renamed just to Field::send().

Note, this change introduces symmetry between Field and Item,
because Items also send themself using a single method Item::send(),
which is used for *all* protocol types.

Performance improvement is achieved by the fact that Protocol_text
implements these data type specific methods using store_numeric_string_aux()
rather than store_string_aux(). The conversion now happens only when
character_set_results is not ASCII compatible character sets
(e.g. UCS2, UTF16, UTF32).

In the old code (before any MDEV-23162 work, e.g. as of 10.5.4),
Protocol_text::store(Field*) used val_str() for all data types.
So the execution went through the character set conversion routines
even for numeric and temporal data types.

Benchmarking summary (see  details in MDEV-23478):

The new approach stably demonstrates additional improvement comparing
to the previous implementation (the smaller time - the better):

Original   - the commit before MDEV-23162
             be98036f

        1m9.336s
        1m9.290s
        1m9.300s

MDEV-23162 - the repertoire optimization

        1m6.101s
        1m5.988s
        1m6.264s

MDEV-23478 - this commit

        1m2.150s
        1m2.079s
        1m2.099s
parent f1a9700f
...@@ -1888,7 +1888,7 @@ void Field::copy_from_tmp(int row_offset) ...@@ -1888,7 +1888,7 @@ void Field::copy_from_tmp(int row_offset)
} }
bool Field::send_binary(Protocol *protocol) bool Field::send(Protocol *protocol)
{ {
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),charset()); String tmp(buff,sizeof(buff),charset());
...@@ -1897,6 +1897,18 @@ bool Field::send_binary(Protocol *protocol) ...@@ -1897,6 +1897,18 @@ bool Field::send_binary(Protocol *protocol)
} }
bool Field_num::send_numeric_zerofill_str(Protocol_text *protocol,
protocol_send_type_t send_type)
{
DBUG_ASSERT(marked_for_read());
StringBuffer<MAX_FIELD_WIDTH> tmp(&my_charset_latin1);
val_str(&tmp);
return protocol->store_numeric_zerofill_str(tmp.ptr(),
tmp.length(),
send_type);
}
/** /**
Check to see if field size is compatible with destination. Check to see if field size is compatible with destination.
...@@ -3855,11 +3867,16 @@ String *Field_tiny::val_str(String *val_buffer, ...@@ -3855,11 +3867,16 @@ String *Field_tiny::val_str(String *val_buffer,
return val_str_from_long(val_buffer, 5, -10, nr); return val_str_from_long(val_buffer, 5, -10, nr);
} }
bool Field_tiny::send_binary(Protocol *protocol) bool Field_tiny::send(Protocol *protocol)
{ {
return protocol->store_tiny((longlong) (int8) ptr[0]); DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_TINY);
return protocol->store_tiny(Field_tiny::val_int());
} }
int Field_tiny::cmp(const uchar *a_ptr, const uchar *b_ptr) const int Field_tiny::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{ {
signed char a,b; signed char a,b;
...@@ -4015,8 +4032,12 @@ String *Field_short::val_str(String *val_buffer, ...@@ -4015,8 +4032,12 @@ String *Field_short::val_str(String *val_buffer,
} }
bool Field_short::send_binary(Protocol *protocol) bool Field_short::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_SHORT);
return protocol->store_short(Field_short::val_int()); return protocol->store_short(Field_short::val_int());
} }
...@@ -4198,9 +4219,12 @@ String *Field_int::val_str_from_long(String *val_buffer, ...@@ -4198,9 +4219,12 @@ String *Field_int::val_str_from_long(String *val_buffer,
} }
bool Field_medium::send_binary(Protocol *protocol) bool Field_medium::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read()); DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_LONG);
return protocol->store_long(Field_medium::val_int()); return protocol->store_long(Field_medium::val_int());
} }
...@@ -4369,12 +4393,16 @@ String *Field_long::val_str(String *val_buffer, ...@@ -4369,12 +4393,16 @@ String *Field_long::val_str(String *val_buffer,
} }
bool Field_long::send_binary(Protocol *protocol) bool Field_long::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read()); DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_LONG);
return protocol->store_long(Field_long::val_int()); return protocol->store_long(Field_long::val_int());
} }
int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr) const int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{ {
int32 a,b; int32 a,b;
...@@ -4506,9 +4534,12 @@ String *Field_longlong::val_str(String *val_buffer, ...@@ -4506,9 +4534,12 @@ String *Field_longlong::val_str(String *val_buffer,
} }
bool Field_longlong::send_binary(Protocol *protocol) bool Field_longlong::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read()); DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_LONGLONG);
return protocol->store_longlong(Field_longlong::val_int(), unsigned_flag); return protocol->store_longlong(Field_longlong::val_int(), unsigned_flag);
} }
...@@ -4686,9 +4717,12 @@ void Field_float::sort_string(uchar *to,uint length __attribute__((unused))) ...@@ -4686,9 +4717,12 @@ void Field_float::sort_string(uchar *to,uint length __attribute__((unused)))
} }
bool Field_float::send_binary(Protocol *protocol) bool Field_float::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read()); DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_FLOAT);
return protocol->store_float((float) Field_float::val_real(), dec); return protocol->store_float((float) Field_float::val_real(), dec);
} }
...@@ -4980,8 +5014,12 @@ String *Field_double::val_str(String *val_buffer, ...@@ -4980,8 +5014,12 @@ String *Field_double::val_str(String *val_buffer,
return val_buffer; return val_buffer;
} }
bool Field_double::send_binary(Protocol *protocol) bool Field_double::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_DOUBLE);
return protocol->store_double(Field_double::val_real(), dec); return protocol->store_double(Field_double::val_real(), dec);
} }
...@@ -5378,7 +5416,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) ...@@ -5378,7 +5416,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
} }
bool Field_timestamp0::send_binary(Protocol *protocol) bool Field_timestamp0::send(Protocol *protocol)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
Field_timestamp0::get_date(&ltime, date_mode_t(0)); Field_timestamp0::get_date(&ltime, date_mode_t(0));
...@@ -5538,7 +5576,7 @@ int Field_timestamp_with_dec::set_time() ...@@ -5538,7 +5576,7 @@ int Field_timestamp_with_dec::set_time()
return 0; return 0;
} }
bool Field_timestamp_with_dec::send_binary(Protocol *protocol) bool Field_timestamp_with_dec::send(Protocol *protocol)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
Field_timestamp::get_date(&ltime, date_mode_t(0)); Field_timestamp::get_date(&ltime, date_mode_t(0));
...@@ -6047,7 +6085,7 @@ bool Field_time0::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) ...@@ -6047,7 +6085,7 @@ bool Field_time0::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
} }
bool Field_time::send_binary(Protocol *protocol) bool Field_time::send(Protocol *protocol)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
get_date(&ltime, Time::Options(TIME_TIME_ONLY, get_thd())); get_date(&ltime, Time::Options(TIME_TIME_ONLY, get_thd()));
...@@ -6369,9 +6407,12 @@ int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) ...@@ -6369,9 +6407,12 @@ int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
return 0; return 0;
} }
bool Field_year::send_binary(Protocol *protocol) bool Field_year::send(Protocol *protocol)
{ {
DBUG_ASSERT(marked_for_read()); DBUG_ASSERT(marked_for_read());
Protocol_text *txt;
if ((txt= dynamic_cast<Protocol_text*>(protocol)))
return send_numeric_zerofill_str(txt, PROTOCOL_SEND_SHORT);
ulonglong tmp= Field_year::val_int(); ulonglong tmp= Field_year::val_int();
return protocol->store_short(tmp); return protocol->store_short(tmp);
} }
...@@ -6506,7 +6547,7 @@ void Field_date::store_TIME(const MYSQL_TIME *ltime) ...@@ -6506,7 +6547,7 @@ void Field_date::store_TIME(const MYSQL_TIME *ltime)
int4store(ptr,tmp); int4store(ptr,tmp);
} }
bool Field_date::send_binary(Protocol *protocol) bool Field_date::send(Protocol *protocol)
{ {
longlong tmp= Field_date::val_int(); longlong tmp= Field_date::val_int();
MYSQL_TIME tm; MYSQL_TIME tm;
...@@ -6600,7 +6641,7 @@ void Field_newdate::store_TIME(const MYSQL_TIME *ltime) ...@@ -6600,7 +6641,7 @@ void Field_newdate::store_TIME(const MYSQL_TIME *ltime)
} }
bool Field_newdate::send_binary(Protocol *protocol) bool Field_newdate::send(Protocol *protocol)
{ {
MYSQL_TIME tm; MYSQL_TIME tm;
Field_newdate::get_date(&tm, date_mode_t(0)); Field_newdate::get_date(&tm, date_mode_t(0));
...@@ -6772,7 +6813,7 @@ Field_datetime::conversion_depends_on_sql_mode(THD *thd, Item *expr) const ...@@ -6772,7 +6813,7 @@ Field_datetime::conversion_depends_on_sql_mode(THD *thd, Item *expr) const
} }
bool Field_datetime0::send_binary(Protocol *protocol) bool Field_datetime0::send(Protocol *protocol)
{ {
MYSQL_TIME tm; MYSQL_TIME tm;
Field_datetime0::get_date(&tm, date_mode_t(0)); Field_datetime0::get_date(&tm, date_mode_t(0));
...@@ -6900,7 +6941,7 @@ void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime) ...@@ -6900,7 +6941,7 @@ void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime)
store_bigendian(packed, ptr, Field_datetime_hires::pack_length()); store_bigendian(packed, ptr, Field_datetime_hires::pack_length());
} }
bool Field_datetime_with_dec::send_binary(Protocol *protocol) bool Field_datetime_with_dec::send(Protocol *protocol)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
get_date(&ltime, date_mode_t(0)); get_date(&ltime, date_mode_t(0));
...@@ -7109,6 +7150,23 @@ void Field_longstr::make_send_field(Send_field *field) ...@@ -7109,6 +7150,23 @@ void Field_longstr::make_send_field(Send_field *field)
} }
} }
/*
An optimized version that uses less stack than Field::send().
*/
bool Field_longstr::send(Protocol *protocol)
{
String tmp;
val_str(&tmp, &tmp);
/*
Ensure this function is only used with classes that do not allocate
memory in val_str()
*/
DBUG_ASSERT(tmp.alloced_length() == 0);
return protocol->store(tmp.ptr(), tmp.length(), tmp.charset());
}
/* Copy a string and fill with space */ /* Copy a string and fill with space */
int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs) int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs)
...@@ -7698,6 +7756,17 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value) ...@@ -7698,6 +7756,17 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
} }
/*
An optimized version that uses less stack and less temporary
variable initialization than Field_longstr::send()
*/
bool Field_varstring::send(Protocol *protocol)
{
return protocol->store((const char *) get_data(), get_length(),
field_charset());
}
#ifdef HAVE_valgrind #ifdef HAVE_valgrind
void Field_varstring::mark_unused_memory_as_defined() void Field_varstring::mark_unused_memory_as_defined()
{ {
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
class Send_field; class Send_field;
class Copy_field; class Copy_field;
class Protocol; class Protocol;
class Protocol_text;
class Create_field; class Create_field;
class Relay_log_info; class Relay_log_info;
class Field; class Field;
...@@ -1576,7 +1577,7 @@ class Field: public Value_source ...@@ -1576,7 +1577,7 @@ class Field: public Value_source
ptr= old_ptr; ptr= old_ptr;
return str; return str;
} }
virtual bool send_binary(Protocol *protocol); virtual bool send(Protocol *protocol);
virtual uchar *pack(uchar *to, const uchar *from, uint max_length); virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
/** /**
...@@ -2005,6 +2006,9 @@ class Field_num :public Field { ...@@ -2005,6 +2006,9 @@ class Field_num :public Field {
return (flags & UNSIGNED_FLAG) ? Binlog_type_info::SIGN_UNSIGNED : return (flags & UNSIGNED_FLAG) ? Binlog_type_info::SIGN_UNSIGNED :
Binlog_type_info::SIGN_SIGNED; Binlog_type_info::SIGN_SIGNED;
} }
bool send_numeric_zerofill_str(Protocol_text *protocol,
protocol_send_type_t send_type);
public: public:
const uint8 dec; const uint8 dec;
bool zerofill,unsigned_flag; // Purify cannot handle bit fields bool zerofill,unsigned_flag; // Purify cannot handle bit fields
...@@ -2194,6 +2198,7 @@ class Field_longstr :public Field_str ...@@ -2194,6 +2198,7 @@ class Field_longstr :public Field_str
int store_decimal(const my_decimal *d) override; int store_decimal(const my_decimal *d) override;
uint32 max_data_length() const override; uint32 max_data_length() const override;
void make_send_field(Send_field *) override; void make_send_field(Send_field *) override;
bool send(Protocol *protocol) override;
bool is_varchar_and_in_write_set() const override bool is_varchar_and_in_write_set() const override
{ {
...@@ -2520,7 +2525,7 @@ class Field_tiny :public Field_int ...@@ -2520,7 +2525,7 @@ class Field_tiny :public Field_int
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 1; } uint32 pack_length() const override { return 1; }
...@@ -2583,7 +2588,7 @@ class Field_short final :public Field_int ...@@ -2583,7 +2588,7 @@ class Field_short final :public Field_int
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 2; } uint32 pack_length() const override { return 2; }
...@@ -2630,7 +2635,7 @@ class Field_medium final :public Field_int ...@@ -2630,7 +2635,7 @@ class Field_medium final :public Field_int
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 3; } uint32 pack_length() const override { return 3; }
...@@ -2681,7 +2686,7 @@ class Field_long final :public Field_int ...@@ -2681,7 +2686,7 @@ class Field_long final :public Field_int
int reset() override { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } int reset() override { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
...@@ -2743,7 +2748,7 @@ class Field_longlong :public Field_int ...@@ -2743,7 +2748,7 @@ class Field_longlong :public Field_int
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 8; } uint32 pack_length() const override { return 8; }
...@@ -2843,7 +2848,7 @@ class Field_float final :public Field_real { ...@@ -2843,7 +2848,7 @@ class Field_float final :public Field_real {
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff, uint length) override; void sort_string(uchar *buff, uint length) override;
uint32 pack_length() const override { return sizeof(float); } uint32 pack_length() const override { return sizeof(float); }
...@@ -2907,7 +2912,7 @@ class Field_double :public Field_real { ...@@ -2907,7 +2912,7 @@ class Field_double :public Field_real {
longlong val_int() override final { return val_int_from_real(false); } longlong val_int() override final { return val_int_from_real(false); }
ulonglong val_uint() override final { return (ulonglong) val_int_from_real(true); } ulonglong val_uint() override final { return (ulonglong) val_int_from_real(true); }
String *val_str(String *, String *) override final; String *val_str(String *, String *) override final;
bool send_binary(Protocol *protocol) override final; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override final; int cmp(const uchar *,const uchar *) const override final;
void sort_string(uchar *buff, uint length) override final; void sort_string(uchar *buff, uint length) override final;
uint32 pack_length() const override final { return sizeof(double); } uint32 pack_length() const override final { return sizeof(double); }
...@@ -3210,7 +3215,7 @@ class Field_timestamp0 :public Field_timestamp ...@@ -3210,7 +3215,7 @@ class Field_timestamp0 :public Field_timestamp
{ {
return (double) Field_timestamp0::val_int(); return (double) Field_timestamp0::val_int();
} }
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 4; } uint32 pack_length() const override { return 4; }
...@@ -3265,7 +3270,7 @@ class Field_timestamp_with_dec :public Field_timestamp { ...@@ -3265,7 +3270,7 @@ class Field_timestamp_with_dec :public Field_timestamp {
DBUG_ASSERT(length == pack_length()); DBUG_ASSERT(length == pack_length());
memcpy(to, ptr, length); memcpy(to, ptr, length);
} }
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
double val_real() override; double val_real() override;
my_decimal* val_decimal(my_decimal*) override; my_decimal* val_decimal(my_decimal*) override;
int set_time() override; int set_time() override;
...@@ -3403,7 +3408,7 @@ class Field_year final :public Field_tiny { ...@@ -3403,7 +3408,7 @@ class Field_year final :public Field_tiny {
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override; bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
Information_schema_numeric_attributes Information_schema_numeric_attributes
information_schema_numeric_attributes() const override information_schema_numeric_attributes() const override
{ {
...@@ -3462,7 +3467,7 @@ class Field_date final :public Field_date_common ...@@ -3462,7 +3467,7 @@ class Field_date final :public Field_date_common
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 4; } uint32 pack_length() const override { return 4; }
...@@ -3501,7 +3506,7 @@ class Field_newdate final :public Field_date_common ...@@ -3501,7 +3506,7 @@ class Field_newdate final :public Field_date_common
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 3; } uint32 pack_length() const override { return 3; }
...@@ -3561,7 +3566,7 @@ class Field_time :public Field_temporal { ...@@ -3561,7 +3566,7 @@ class Field_time :public Field_temporal {
int store(longlong nr, bool unsigned_val) override; int store(longlong nr, bool unsigned_val) override;
int store_decimal(const my_decimal *) override; int store_decimal(const my_decimal *) override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
void set_curdays(THD *thd); void set_curdays(THD *thd);
Field *new_key_field(MEM_ROOT *root, TABLE *new_table, Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
uchar *new_ptr, uint32 length, uchar *new_ptr, uint32 length,
...@@ -3775,7 +3780,7 @@ class Field_datetime0 final :public Field_datetime ...@@ -3775,7 +3780,7 @@ class Field_datetime0 final :public Field_datetime
} }
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override; bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override; int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override; void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 8; } uint32 pack_length() const override { return 8; }
...@@ -3815,7 +3820,7 @@ class Field_datetime_with_dec :public Field_datetime { ...@@ -3815,7 +3820,7 @@ class Field_datetime_with_dec :public Field_datetime {
uint decimals() const override final { return dec; } uint decimals() const override final { return dec; }
enum ha_base_keytype key_type() const override final { return HA_KEYTYPE_BINARY; } enum ha_base_keytype key_type() const override final { return HA_KEYTYPE_BINARY; }
void make_send_field(Send_field *field) override final; void make_send_field(Send_field *field) override final;
bool send_binary(Protocol *protocol) override final; bool send(Protocol *protocol) override final;
uchar *pack(uchar *to, const uchar *from, uint max_length) override final uchar *pack(uchar *to, const uchar *from, uint max_length) override final
{ return Field::pack(to, from, max_length); } { return Field::pack(to, from, max_length); }
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
...@@ -4153,6 +4158,7 @@ class Field_varstring :public Field_longstr { ...@@ -4153,6 +4158,7 @@ class Field_varstring :public Field_longstr {
longlong val_int() override; longlong val_int() override;
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
my_decimal *val_decimal(my_decimal *) override; my_decimal *val_decimal(my_decimal *) override;
bool send(Protocol *protocol) override;
int cmp(const uchar *a,const uchar *b) const override; int cmp(const uchar *a,const uchar *b) const override;
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len) const int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len) const
override; override;
...@@ -4217,6 +4223,15 @@ class Field_varstring_compressed final :public Field_varstring { ...@@ -4217,6 +4223,15 @@ class Field_varstring_compressed final :public Field_varstring {
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
uint size_of() const override { return sizeof *this; } uint size_of() const override { return sizeof *this; }
/*
We use the default Field::send() implementation,
because the derived optimized version (from Field_longstr)
is not suitable for compressed fields.
*/
bool send(Protocol *protocol) override
{
return Field::send(protocol);
}
enum_field_types binlog_type() const override enum_field_types binlog_type() const override
{ return MYSQL_TYPE_VARCHAR_COMPRESSED; } { return MYSQL_TYPE_VARCHAR_COMPRESSED; }
void sql_type(String &str) const override void sql_type(String &str) const override
...@@ -4614,6 +4629,15 @@ class Field_blob_compressed final :public Field_blob { ...@@ -4614,6 +4629,15 @@ class Field_blob_compressed final :public Field_blob {
String *val_str(String *, String *) override; String *val_str(String *, String *) override;
double val_real() override; double val_real() override;
longlong val_int() override; longlong val_int() override;
/*
We use the default Field::send() implementation,
because the derived optimized version (from Field_longstr)
is not suitable for compressed fields.
*/
bool send(Protocol *protocol) override
{
return Field::send(protocol);
}
uint size_of() const override { return sizeof *this; } uint size_of() const override { return sizeof *this; }
enum_field_types binlog_type() const override enum_field_types binlog_type() const override
{ return MYSQL_TYPE_BLOB_COMPRESSED; } { return MYSQL_TYPE_BLOB_COMPRESSED; }
......
...@@ -1232,6 +1232,22 @@ bool Protocol_text::store_str(const char *from, size_t length, ...@@ -1232,6 +1232,22 @@ bool Protocol_text::store_str(const char *from, size_t length,
} }
bool Protocol_text::store_numeric_zerofill_str(const char *from,
size_t length,
protocol_send_type_t send_type)
{
#ifndef DBUG_OFF
DBUG_PRINT("info",
("Protocol_text::store_numeric_zerofill_str field %u : %.*b",
field_pos, (int) length, (length == 0 ? "" : from)));
DBUG_ASSERT(field_handlers == 0 || field_pos < field_count);
DBUG_ASSERT(valid_handler(field_pos, send_type));
field_pos++;
#endif
return store_numeric_string_aux(from, length);
}
bool Protocol_text::store_tiny(longlong from) bool Protocol_text::store_tiny(longlong from)
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -1321,12 +1337,6 @@ bool Protocol_text::store(Field *field) ...@@ -1321,12 +1337,6 @@ bool Protocol_text::store(Field *field)
{ {
if (field->is_null()) if (field->is_null())
return store_null(); return store_null();
#ifndef DBUG_OFF
field_pos++;
#endif
char buff[MAX_FIELD_WIDTH];
String str(buff,sizeof(buff), &my_charset_bin);
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
#ifdef DBUG_ASSERT_EXISTS #ifdef DBUG_ASSERT_EXISTS
TABLE *table= field->table; TABLE *table= field->table;
my_bitmap_map *old_map= 0; my_bitmap_map *old_map= 0;
...@@ -1334,13 +1344,14 @@ bool Protocol_text::store(Field *field) ...@@ -1334,13 +1344,14 @@ bool Protocol_text::store(Field *field)
old_map= dbug_tmp_use_all_columns(table, table->read_set); old_map= dbug_tmp_use_all_columns(table, table->read_set);
#endif #endif
field->val_str(&str); bool rc= field->send(this);
#ifdef DBUG_ASSERT_EXISTS #ifdef DBUG_ASSERT_EXISTS
if (old_map) if (old_map)
dbug_tmp_restore_column_map(table->read_set, old_map); dbug_tmp_restore_column_map(table->read_set, old_map);
#endif #endif
return store_string_aux(str.ptr(), str.length(), str.charset(), tocs); return rc;
} }
...@@ -1553,12 +1564,12 @@ bool Protocol_binary::store_double(double from, uint32 decimals) ...@@ -1553,12 +1564,12 @@ bool Protocol_binary::store_double(double from, uint32 decimals)
bool Protocol_binary::store(Field *field) bool Protocol_binary::store(Field *field)
{ {
/* /*
We should not increment field_pos here as send_binary() will call another We should not increment field_pos here as send() will call another
protocol function to do this for us protocol function to do this for us
*/ */
if (field->is_null()) if (field->is_null())
return store_null(); return store_null();
return field->send_binary(this); return field->send(this);
} }
......
...@@ -219,6 +219,10 @@ class Protocol_text final :public Protocol ...@@ -219,6 +219,10 @@ class Protocol_text final :public Protocol
bool store(Field *field) override; bool store(Field *field) override;
bool send_out_parameters(List<Item_param> *sp_params) override; bool send_out_parameters(List<Item_param> *sp_params) override;
bool store_numeric_zerofill_str(const char *from, size_t length,
protocol_send_type_t send_type);
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
void remove_last_row() override; void remove_last_row() override;
#endif #endif
......
...@@ -5390,7 +5390,7 @@ bool Protocol_local::store(Field *field) ...@@ -5390,7 +5390,7 @@ bool Protocol_local::store(Field *field)
{ {
if (field->is_null()) if (field->is_null())
return store_null(); return store_null();
return field->send_binary(this); return field->send(this);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment