Commit be98036f authored by Alexander Barkov's avatar Alexander Barkov

Preparatory changes for MDEV-23162 Improve Protocol performance for numeric data

- Renaming this virtual method store() to store_str():
    store(const char *str, size_t length, CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs)
  We'll be adding more variants of store*() soon. This change will help to avoid
  ambiguities during overloading.

- Adding a helper method store_ident().

- Renaming store_str(const LEX_CSTRING &s...) to store_lex_cstring(),
  to avoid ambiguties during overloading.

- Adding a helper method store() for backward compatibility, to avoid a lot of
  changes in the code now. But eventually we should replace store() to
  non-ambiguius methods store_str() or store_ident().

- Adding a helper method Protocol::needs_conversion() and reusing it
  in two places.
parent c3afcc7c
...@@ -43,6 +43,12 @@ bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count); ...@@ -43,6 +43,12 @@ bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
static bool write_eof_packet(THD *, NET *, uint, uint); static bool write_eof_packet(THD *, NET *, uint, uint);
#endif #endif
CHARSET_INFO *Protocol::character_set_results() const
{
return thd->variables.character_set_results;
}
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
bool Protocol::net_store_data(const uchar *from, size_t length) bool Protocol::net_store_data(const uchar *from, size_t length)
#else #else
...@@ -846,12 +852,13 @@ bool Protocol_text::store_field_metadata(const THD * thd, ...@@ -846,12 +852,13 @@ bool Protocol_text::store_field_metadata(const THD * thd,
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{ {
if (store(STRING_WITH_LEN("def"), cs, thd_charset) || const LEX_CSTRING def= {STRING_WITH_LEN("def")};
store_str(field.db_name, cs, thd_charset) || if (store_ident(def) ||
store_str(field.table_name, cs, thd_charset) || store_ident(field.db_name) ||
store_str(field.org_table_name, cs, thd_charset) || store_ident(field.table_name) ||
store_str(field.col_name, cs, thd_charset) || store_ident(field.org_table_name) ||
store_str(field.org_col_name, cs, thd_charset)) store_ident(field.col_name) ||
store_ident(field.org_col_name))
return true; return true;
if (thd->client_capabilities & MARIADB_CLIENT_EXTENDED_METADATA) if (thd->client_capabilities & MARIADB_CLIENT_EXTENDED_METADATA)
{ {
...@@ -861,7 +868,7 @@ bool Protocol_text::store_field_metadata(const THD * thd, ...@@ -861,7 +868,7 @@ bool Protocol_text::store_field_metadata(const THD * thd,
Don't apply character set conversion: Don't apply character set conversion:
extended metadata is a binary encoded data. extended metadata is a binary encoded data.
*/ */
if (store_str(metadata.lex_cstring(), cs, &my_charset_bin)) if (store_lex_cstring(metadata.lex_cstring(), cs, &my_charset_bin))
return true; return true;
} }
if (packet->realloc(packet->length() + 12)) if (packet->realloc(packet->length() + 12))
...@@ -894,8 +901,8 @@ bool Protocol_text::store_field_metadata(const THD * thd, ...@@ -894,8 +901,8 @@ bool Protocol_text::store_field_metadata(const THD * thd,
} }
else else
{ {
if (store_str(field.table_name, cs, thd_charset) || if (store_ident(field.table_name) ||
store_str(field.col_name, cs, thd_charset) || store_ident(field.col_name) ||
packet->realloc(packet->length() + 10)) packet->realloc(packet->length() + 10))
return true; return true;
pos= (char*) packet->end(); pos= (char*) packet->end();
...@@ -1178,9 +1185,7 @@ bool Protocol::store_string_aux(const char *from, size_t length, ...@@ -1178,9 +1185,7 @@ bool Protocol::store_string_aux(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs) CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{ {
/* 'tocs' is set 0 when client issues SET character_set_results=NULL */ /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
if (tocs && !my_charset_same(fromcs, tocs) && if (needs_conversion(fromcs, tocs))
fromcs != &my_charset_bin &&
tocs != &my_charset_bin)
{ {
/* Store with conversion */ /* Store with conversion */
return net_store_data_cs((uchar*) from, length, fromcs, tocs); return net_store_data_cs((uchar*) from, length, fromcs, tocs);
...@@ -1202,8 +1207,8 @@ bool Protocol::store_warning(const char *from, size_t length) ...@@ -1202,8 +1207,8 @@ bool Protocol::store_warning(const char *from, size_t length)
} }
bool Protocol_text::store(const char *from, size_t length, bool Protocol_text::store_str(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs) CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %.*b", field_pos, DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %.*b", field_pos,
...@@ -1216,14 +1221,6 @@ bool Protocol_text::store(const char *from, size_t length, ...@@ -1216,14 +1221,6 @@ bool Protocol_text::store(const char *from, size_t length,
} }
bool Protocol::store(const char *from, size_t length,
CHARSET_INFO *fromcs)
{
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
return store(from, length, fromcs, tocs);
}
bool Protocol_text::store_tiny(longlong from) bool Protocol_text::store_tiny(longlong from)
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -1451,8 +1448,8 @@ void Protocol_binary::prepare_for_resend() ...@@ -1451,8 +1448,8 @@ void Protocol_binary::prepare_for_resend()
} }
bool Protocol_binary::store(const char *from, size_t length, bool Protocol_binary::store_str(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs) CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{ {
field_pos++; field_pos++;
return store_string_aux(from, length, fromcs, tocs); return store_string_aux(from, length, fromcs, tocs);
...@@ -1517,8 +1514,8 @@ bool Protocol_binary::store_decimal(const my_decimal *d) ...@@ -1517,8 +1514,8 @@ bool Protocol_binary::store_decimal(const my_decimal *d)
#endif #endif
StringBuffer<DECIMAL_MAX_STR_LENGTH> str; StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
(void) d->to_string(&str); (void) d->to_string(&str);
return store(str.ptr(), str.length(), str.charset(), return store_str(str.ptr(), str.length(), str.charset(),
thd->variables.character_set_results); thd->variables.character_set_results);
} }
bool Protocol_binary::store(float from, uint32 decimals, String *buffer) bool Protocol_binary::store(float from, uint32 decimals, String *buffer)
......
...@@ -61,6 +61,14 @@ class Protocol ...@@ -61,6 +61,14 @@ class Protocol
MYSQL_FIELD *next_mysql_field; MYSQL_FIELD *next_mysql_field;
MEM_ROOT *alloc; MEM_ROOT *alloc;
#endif #endif
bool needs_conversion(CHARSET_INFO *fromcs,
CHARSET_INFO *tocs) const
{
// 'tocs' is set 0 when client issues SET character_set_results=NULL
return tocs && !my_charset_same(fromcs, tocs) &&
fromcs != &my_charset_bin &&
tocs != &my_charset_bin;
}
/* /*
The following two are low-level functions that are invoked from The following two are low-level functions that are invoked from
higher-level store_xxx() funcs. The data is stored into this->packet. higher-level store_xxx() funcs. The data is stored into this->packet.
...@@ -77,6 +85,8 @@ class Protocol ...@@ -77,6 +85,8 @@ class Protocol
virtual bool send_error(uint sql_errno, const char *err_msg, virtual bool send_error(uint sql_errno, const char *err_msg,
const char *sql_state); const char *sql_state);
CHARSET_INFO *character_set_results() const;
public: public:
THD *thd; THD *thd;
Protocol(THD *thd_arg) { init(thd_arg); } Protocol(THD *thd_arg) { init(thd_arg); }
...@@ -120,13 +130,8 @@ class Protocol ...@@ -120,13 +130,8 @@ class Protocol
virtual bool store_long(longlong from)=0; virtual bool store_long(longlong from)=0;
virtual bool store_longlong(longlong from, bool unsigned_flag)=0; virtual bool store_longlong(longlong from, bool unsigned_flag)=0;
virtual bool store_decimal(const my_decimal *)=0; virtual bool store_decimal(const my_decimal *)=0;
bool store(const char *from, size_t length, CHARSET_INFO *cs); virtual bool store_str(const char *from, size_t length,
virtual bool store(const char *from, size_t length, CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
bool store_str(const LEX_CSTRING &s, CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
return store(s.str, (uint) s.length, fromcs, tocs);
}
virtual bool store(float from, uint32 decimals, String *buffer)=0; virtual bool store(float from, uint32 decimals, String *buffer)=0;
virtual bool store(double from, uint32 decimals, String *buffer)=0; virtual bool store(double from, uint32 decimals, String *buffer)=0;
virtual bool store(MYSQL_TIME *time, int decimals)=0; virtual bool store(MYSQL_TIME *time, int decimals)=0;
...@@ -134,6 +139,24 @@ class Protocol ...@@ -134,6 +139,24 @@ class Protocol
virtual bool store_time(MYSQL_TIME *time, int decimals)=0; virtual bool store_time(MYSQL_TIME *time, int decimals)=0;
virtual bool store(Field *field)=0; virtual bool store(Field *field)=0;
// Various useful wrappers for the virtual store*() methods.
// Backward wrapper for store_str()
bool store(const char *from, size_t length, CHARSET_INFO *cs)
{
return store_str(from, length, cs, character_set_results());
}
bool store_lex_cstring(const LEX_CSTRING &s,
CHARSET_INFO *fromcs,
CHARSET_INFO *tocs)
{
return store_str(s.str, (uint) s.length, fromcs, tocs);
}
bool store_ident(const LEX_CSTRING &s)
{
return store_lex_cstring(s, system_charset_info, character_set_results());
}
// End of wrappers
virtual bool send_out_parameters(List<Item_param> *sp_params)=0; virtual bool send_out_parameters(List<Item_param> *sp_params)=0;
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
bool begin_dataset(); bool begin_dataset();
...@@ -178,8 +201,8 @@ class Protocol_text :public Protocol ...@@ -178,8 +201,8 @@ class Protocol_text :public Protocol
virtual bool store_long(longlong from); virtual bool store_long(longlong from);
virtual bool store_longlong(longlong from, bool unsigned_flag); virtual bool store_longlong(longlong from, bool unsigned_flag);
virtual bool store_decimal(const my_decimal *); virtual bool store_decimal(const my_decimal *);
virtual bool store(const char *from, size_t length, virtual bool store_str(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs); CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
virtual bool store(MYSQL_TIME *time, int decimals); virtual bool store(MYSQL_TIME *time, int decimals);
virtual bool store_date(MYSQL_TIME *time); virtual bool store_date(MYSQL_TIME *time);
virtual bool store_time(MYSQL_TIME *time, int decimals); virtual bool store_time(MYSQL_TIME *time, int decimals);
...@@ -222,8 +245,8 @@ class Protocol_binary :public Protocol ...@@ -222,8 +245,8 @@ class Protocol_binary :public Protocol
virtual bool store_long(longlong from); virtual bool store_long(longlong from);
virtual bool store_longlong(longlong from, bool unsigned_flag); virtual bool store_longlong(longlong from, bool unsigned_flag);
virtual bool store_decimal(const my_decimal *); virtual bool store_decimal(const my_decimal *);
virtual bool store(const char *from, size_t length, virtual bool store_str(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs); CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
virtual bool store(MYSQL_TIME *time, int decimals); virtual bool store(MYSQL_TIME *time, int decimals);
virtual bool store_date(MYSQL_TIME *time); virtual bool store_date(MYSQL_TIME *time);
virtual bool store_time(MYSQL_TIME *time, int decimals); virtual bool store_time(MYSQL_TIME *time, int decimals);
...@@ -270,7 +293,10 @@ class Protocol_discard : public Protocol_text ...@@ -270,7 +293,10 @@ class Protocol_discard : public Protocol_text
bool store_long(longlong) { return false; } bool store_long(longlong) { return false; }
bool store_longlong(longlong, bool) { return false; } bool store_longlong(longlong, bool) { return false; }
bool store_decimal(const my_decimal *) { return false; } bool store_decimal(const my_decimal *) { return false; }
bool store(const char *, size_t, CHARSET_INFO *, CHARSET_INFO *) { return false; } bool store_str(const char *, size_t, CHARSET_INFO *, CHARSET_INFO *)
{
return false;
}
bool store(MYSQL_TIME *, int) { return false; } bool store(MYSQL_TIME *, int) { return false; }
bool store_date(MYSQL_TIME *) { return false; } bool store_date(MYSQL_TIME *) { return false; }
bool store_time(MYSQL_TIME *, int) { return false; } bool store_time(MYSQL_TIME *, int) { return false; }
......
...@@ -262,9 +262,8 @@ class Protocol_local :public Protocol ...@@ -262,9 +262,8 @@ class Protocol_local :public Protocol
virtual bool store_long(longlong from); virtual bool store_long(longlong from);
virtual bool store_longlong(longlong from, bool unsigned_flag); virtual bool store_longlong(longlong from, bool unsigned_flag);
virtual bool store_decimal(const my_decimal *); virtual bool store_decimal(const my_decimal *);
virtual bool store(const char *from, size_t length, CHARSET_INFO *cs); virtual bool store_str(const char *from, size_t length,
virtual bool store(const char *from, size_t length, CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
virtual bool store(MYSQL_TIME *time, int decimals); virtual bool store(MYSQL_TIME *time, int decimals);
virtual bool store_date(MYSQL_TIME *time); virtual bool store_date(MYSQL_TIME *time);
virtual bool store_time(MYSQL_TIME *time, int decimals); virtual bool store_time(MYSQL_TIME *time, int decimals);
...@@ -5275,9 +5274,7 @@ Protocol_local::store_string(const char *str, size_t length, ...@@ -5275,9 +5274,7 @@ Protocol_local::store_string(const char *str, size_t length,
/* Store with conversion */ /* Store with conversion */
uint error_unused; uint error_unused;
if (dst_cs && !my_charset_same(src_cs, dst_cs) && if (needs_conversion(src_cs, dst_cs))
src_cs != &my_charset_bin &&
dst_cs != &my_charset_bin)
{ {
if (unlikely(convert->copy(str, length, src_cs, dst_cs, &error_unused))) if (unlikely(convert->copy(str, length, src_cs, dst_cs, &error_unused)))
return TRUE; return TRUE;
...@@ -5334,22 +5331,10 @@ bool Protocol_local::store_decimal(const my_decimal *value) ...@@ -5334,22 +5331,10 @@ bool Protocol_local::store_decimal(const my_decimal *value)
} }
/** Convert to cs_results and store a string. */
bool Protocol_local::store(const char *str, size_t length,
CHARSET_INFO *src_cs)
{
CHARSET_INFO *dst_cs;
dst_cs= m_connection->m_thd->variables.character_set_results;
return store_string(str, length, src_cs, dst_cs);
}
/** Store a string. */ /** Store a string. */
bool Protocol_local::store(const char *str, size_t length, bool Protocol_local::store_str(const char *str, size_t length,
CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs) CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs)
{ {
return store_string(str, length, src_cs, dst_cs); return store_string(str, length, src_cs, dst_cs);
} }
......
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