Commit eb2eaba7 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23162 Improve Protocol performance for numeric data

Avoid character set conversion for numeric data in this scenario:

SET NAMES utf8;
CREATE OR REPLACE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
SELECT a FROM t1;
parent be98036f
...@@ -853,7 +853,7 @@ bool Protocol_text::store_field_metadata(const THD * thd, ...@@ -853,7 +853,7 @@ bool Protocol_text::store_field_metadata(const THD * thd,
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{ {
const LEX_CSTRING def= {STRING_WITH_LEN("def")}; const LEX_CSTRING def= {STRING_WITH_LEN("def")};
if (store_ident(def) || if (store_ident(def, MY_REPERTOIRE_ASCII) ||
store_ident(field.db_name) || store_ident(field.db_name) ||
store_ident(field.table_name) || store_ident(field.table_name) ||
store_ident(field.org_table_name) || store_ident(field.org_table_name) ||
...@@ -868,7 +868,8 @@ bool Protocol_text::store_field_metadata(const THD * thd, ...@@ -868,7 +868,8 @@ 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_lex_cstring(metadata.lex_cstring(), cs, &my_charset_bin)) if (store_lex_cstring(metadata.lex_cstring(), cs,
MY_REPERTOIRE_UNICODE30, &my_charset_bin))
return true; return true;
} }
if (packet->realloc(packet->length() + 12)) if (packet->realloc(packet->length() + 12))
...@@ -1182,10 +1183,12 @@ bool Protocol_text::store_null() ...@@ -1182,10 +1183,12 @@ bool Protocol_text::store_null()
*/ */
bool Protocol::store_string_aux(const char *from, size_t length, bool Protocol::store_string_aux(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs) CHARSET_INFO *fromcs,
my_repertoire_t from_repertoire,
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 (needs_conversion(fromcs, tocs)) if (needs_conversion(fromcs, from_repertoire, tocs))
{ {
/* 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);
...@@ -1208,7 +1211,9 @@ bool Protocol::store_warning(const char *from, size_t length) ...@@ -1208,7 +1211,9 @@ bool Protocol::store_warning(const char *from, size_t length)
bool Protocol_text::store_str(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,
my_repertoire_t from_repertoire,
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,
...@@ -1217,7 +1222,7 @@ bool Protocol_text::store_str(const char *from, size_t length, ...@@ -1217,7 +1222,7 @@ bool Protocol_text::store_str(const char *from, size_t length,
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_STRING)); DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_STRING));
field_pos++; field_pos++;
#endif #endif
return store_string_aux(from, length, fromcs, tocs); return store_string_aux(from, length, fromcs, from_repertoire, tocs);
} }
...@@ -1330,7 +1335,8 @@ bool Protocol_text::store(Field *field) ...@@ -1330,7 +1335,8 @@ bool Protocol_text::store(Field *field)
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 store_string_aux(str.ptr(), str.length(), str.charset(),
field->dtcollation().repertoire, tocs);
} }
...@@ -1449,10 +1455,12 @@ void Protocol_binary::prepare_for_resend() ...@@ -1449,10 +1455,12 @@ void Protocol_binary::prepare_for_resend()
bool Protocol_binary::store_str(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,
my_repertoire_t from_repertoire,
CHARSET_INFO *tocs)
{ {
field_pos++; field_pos++;
return store_string_aux(from, length, fromcs, tocs); return store_string_aux(from, length, fromcs, from_repertoire, tocs);
} }
bool Protocol_binary::store_null() bool Protocol_binary::store_null()
...@@ -1515,6 +1523,7 @@ bool Protocol_binary::store_decimal(const my_decimal *d) ...@@ -1515,6 +1523,7 @@ bool Protocol_binary::store_decimal(const my_decimal *d)
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(str.ptr(), str.length(), str.charset(), return store_str(str.ptr(), str.length(), str.charset(),
MY_REPERTOIRE_ASCII,
thd->variables.character_set_results); thd->variables.character_set_results);
} }
......
...@@ -62,19 +62,25 @@ class Protocol ...@@ -62,19 +62,25 @@ class Protocol
MEM_ROOT *alloc; MEM_ROOT *alloc;
#endif #endif
bool needs_conversion(CHARSET_INFO *fromcs, bool needs_conversion(CHARSET_INFO *fromcs,
my_repertoire_t from_repertoire,
CHARSET_INFO *tocs) const CHARSET_INFO *tocs) const
{ {
// 'tocs' is set 0 when client issues SET character_set_results=NULL // 'tocs' is set 0 when client issues SET character_set_results=NULL
return tocs && !my_charset_same(fromcs, tocs) && return tocs && !my_charset_same(fromcs, tocs) &&
fromcs != &my_charset_bin && fromcs != &my_charset_bin &&
tocs != &my_charset_bin; tocs != &my_charset_bin &&
(from_repertoire != MY_REPERTOIRE_ASCII ||
(fromcs->state & MY_CS_NONASCII) ||
(tocs->state & MY_CS_NONASCII));
} }
/* /*
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.
*/ */
bool store_string_aux(const char *from, size_t length, bool store_string_aux(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs); CHARSET_INFO *fromcs,
my_repertoire_t from_repertoire,
CHARSET_INFO *tocs);
virtual bool send_ok(uint server_status, uint statement_warn_count, virtual bool send_ok(uint server_status, uint statement_warn_count,
ulonglong affected_rows, ulonglong last_insert_id, ulonglong affected_rows, ulonglong last_insert_id,
...@@ -131,7 +137,9 @@ class Protocol ...@@ -131,7 +137,9 @@ class Protocol
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;
virtual bool store_str(const char *from, size_t length, virtual bool store_str(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0; CHARSET_INFO *fromcs,
my_repertoire_t from_repertoire,
CHARSET_INFO *tocs)=0;
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;
...@@ -141,19 +149,23 @@ class Protocol ...@@ -141,19 +149,23 @@ class Protocol
// Various useful wrappers for the virtual store*() methods. // Various useful wrappers for the virtual store*() methods.
// Backward wrapper for store_str() // Backward wrapper for store_str()
bool store(const char *from, size_t length, CHARSET_INFO *cs) bool store(const char *from, size_t length, CHARSET_INFO *cs,
my_repertoire_t repertoire= MY_REPERTOIRE_UNICODE30)
{ {
return store_str(from, length, cs, character_set_results()); return store_str(from, length, cs, repertoire, character_set_results());
} }
bool store_lex_cstring(const LEX_CSTRING &s, bool store_lex_cstring(const LEX_CSTRING &s,
CHARSET_INFO *fromcs, CHARSET_INFO *fromcs,
my_repertoire_t from_repertoire,
CHARSET_INFO *tocs) CHARSET_INFO *tocs)
{ {
return store_str(s.str, (uint) s.length, fromcs, tocs); return store_str(s.str, (uint) s.length, fromcs, from_repertoire, tocs);
} }
bool store_ident(const LEX_CSTRING &s) bool store_ident(const LEX_CSTRING &s,
my_repertoire_t repertoire= MY_REPERTOIRE_UNICODE30)
{ {
return store_lex_cstring(s, system_charset_info, character_set_results()); return store_lex_cstring(s, system_charset_info, repertoire,
character_set_results());
} }
// End of wrappers // End of wrappers
...@@ -202,7 +214,9 @@ class Protocol_text :public Protocol ...@@ -202,7 +214,9 @@ class Protocol_text :public Protocol
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_str(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,
my_repertoire_t from_repertoire,
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);
...@@ -246,7 +260,9 @@ class Protocol_binary :public Protocol ...@@ -246,7 +260,9 @@ class Protocol_binary :public Protocol
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_str(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,
my_repertoire_t from_repertoire,
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);
...@@ -293,7 +309,8 @@ class Protocol_discard : public Protocol_text ...@@ -293,7 +309,8 @@ 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_str(const char *, size_t, CHARSET_INFO *, CHARSET_INFO *) bool store_str(const char *, size_t, CHARSET_INFO *, my_repertoire_t,
CHARSET_INFO *)
{ {
return false; return false;
} }
......
...@@ -263,7 +263,9 @@ class Protocol_local :public Protocol ...@@ -263,7 +263,9 @@ class Protocol_local :public Protocol
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_str(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,
my_repertoire_t from_repertoire,
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);
...@@ -286,7 +288,9 @@ class Protocol_local :public Protocol ...@@ -286,7 +288,9 @@ class Protocol_local :public Protocol
virtual bool send_error(uint sql_errno, const char *err_msg, const char* sqlstate); virtual bool send_error(uint sql_errno, const char *err_msg, const char* sqlstate);
private: private:
bool store_string(const char *str, size_t length, bool store_string(const char *str, size_t length,
CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs); CHARSET_INFO *src_cs,
my_repertoire_t src_repertoire,
CHARSET_INFO *dst_cs);
bool store_column(const void *data, size_t length); bool store_column(const void *data, size_t length);
void opt_add_row_to_rset(); void opt_add_row_to_rset();
...@@ -5269,12 +5273,14 @@ bool Protocol_local::store_column(const void *data, size_t length) ...@@ -5269,12 +5273,14 @@ bool Protocol_local::store_column(const void *data, size_t length)
bool bool
Protocol_local::store_string(const char *str, size_t length, Protocol_local::store_string(const char *str, size_t length,
CHARSET_INFO *src_cs, CHARSET_INFO *dst_cs) CHARSET_INFO *src_cs,
my_repertoire_t src_repertoire,
CHARSET_INFO *dst_cs)
{ {
/* Store with conversion */ /* Store with conversion */
uint error_unused; uint error_unused;
if (needs_conversion(src_cs, dst_cs)) if (needs_conversion(src_cs, src_repertoire, dst_cs))
{ {
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,9 +5340,11 @@ bool Protocol_local::store_decimal(const my_decimal *value) ...@@ -5334,9 +5340,11 @@ bool Protocol_local::store_decimal(const my_decimal *value)
/** Store a string. */ /** Store a string. */
bool Protocol_local::store_str(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,
my_repertoire_t from_repertoire,
CHARSET_INFO *dst_cs)
{ {
return store_string(str, length, src_cs, dst_cs); return store_string(str, length, src_cs, from_repertoire, 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