mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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;
This commit is contained in:
@ -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,
|
|||||||
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()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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()
|
|||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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 @@ protected:
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
|
|
||||||
// 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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ protected:
|
|||||||
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 @@ protected:
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
/** 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user