diff options
-rw-r--r-- | sql/protocol.cc | 71 | ||||
-rw-r--r-- | sql/protocol.h | 6 | ||||
-rw-r--r-- | sql/sql_class.h | 2 |
3 files changed, 64 insertions, 15 deletions
diff --git a/sql/protocol.cc b/sql/protocol.cc index 2d53d545066..f82981bd309 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -526,13 +526,16 @@ bool Protocol::send_fields(List<Item> *list, uint flag) if (thd->client_capabilities & CLIENT_PROTOCOL_41) { - if (prot.store(field.db_name, (uint) strlen(field.db_name), cs) || - prot.store(field.table_name, (uint) strlen(field.table_name), cs) || - prot.store(field.org_table_name, - (uint) strlen(field.org_table_name), cs) || - prot.store(field.col_name, (uint) strlen(field.col_name), cs) || - prot.store(field.org_col_name, - (uint) strlen(field.org_col_name), cs) || + if (prot.store(field.db_name, (uint) strlen(field.db_name), + cs, thd->charset()) || + prot.store(field.table_name, (uint) strlen(field.table_name), + cs, thd->charset()) || + prot.store(field.org_table_name, (uint) strlen(field.org_table_name), + cs, thd->charset()) || + prot.store(field.col_name, (uint) strlen(field.col_name), + cs, thd->charset()) || + prot.store(field.org_col_name, (uint) strlen(field.org_col_name), + cs, thd->charset()) || packet->realloc(packet->length()+12)) goto err; /* Store fixed length fields */ @@ -549,8 +552,10 @@ bool Protocol::send_fields(List<Item> *list, uint flag) } else { - if (prot.store(field.table_name, (uint) strlen(field.table_name), cs) || - prot.store(field.col_name, (uint) strlen(field.col_name), cs) || + if (prot.store(field.table_name, (uint) strlen(field.table_name), + cs, thd->charset()) || + prot.store(field.col_name, (uint) strlen(field.col_name), + cs, thd->charset()) || packet->realloc(packet->length()+10)) goto err; pos= (char*) packet->ptr()+packet->length(); @@ -694,7 +699,8 @@ bool Protocol_simple::store_null() #endif -bool Protocol_simple::store(const char *from, uint length, CHARSET_INFO *cs) +bool Protocol_simple::store(const char *from, uint length, + CHARSET_INFO *fromcs, CHARSET_INFO *tocs) { #ifndef DEBUG_OFF DBUG_ASSERT(field_types == 0 || @@ -703,12 +709,34 @@ bool Protocol_simple::store(const char *from, uint length, CHARSET_INFO *cs) field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); field_pos++; #endif - if (!my_charset_same(cs, this->thd->charset()) && - (cs != &my_charset_bin) && - (this->thd->charset() != &my_charset_bin) && - (this->thd->variables.convert_result_charset)) + if (!my_charset_same(fromcs, tocs) && + (fromcs != &my_charset_bin) && + (tocs != &my_charset_bin)) { - convert.copy(from, length, cs, this->thd->charset()); + convert.copy(from, length, fromcs, tocs); + return net_store_data(convert.ptr(), convert.length()); + } + else + return net_store_data(from, length); +} + + +bool Protocol_simple::store(const char *from, uint length, + CHARSET_INFO *fromcs) +{ + CHARSET_INFO *tocs= this->thd->result_charset(fromcs); +#ifndef DEBUG_OFF + DBUG_ASSERT(field_types == 0 || + field_types[field_pos] == MYSQL_TYPE_DECIMAL || + (field_types[field_pos] >= MYSQL_TYPE_ENUM && + field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); + field_pos++; +#endif + if (!my_charset_same(fromcs, tocs) && + (fromcs != &my_charset_bin) && + (tocs != &my_charset_bin)) + { + convert.copy(from, length, fromcs, tocs); return net_store_data(convert.ptr(), convert.length()); } else @@ -923,6 +951,19 @@ bool Protocol_prep::store(const char *from,uint length, CHARSET_INFO *cs) return net_store_data(from, length); } +bool Protocol_prep::store(const char *from,uint length, + CHARSET_INFO *fromcs, CHARSET_INFO *tocs) +{ +#ifndef DEBUG_OFF + DBUG_ASSERT(field_types == 0 || + field_types[field_pos] == MYSQL_TYPE_DECIMAL || + (field_types[field_pos] >= MYSQL_TYPE_ENUM && + field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); +#endif + field_pos++; + return net_store_data(from, length); +} + bool Protocol_prep::store_null() { uint offset= (field_pos+2)/8+1, bit= (1 << ((field_pos+2) & 7)); diff --git a/sql/protocol.h b/sql/protocol.h index 418814a9623..89b838ff6e4 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -74,6 +74,8 @@ public: virtual bool store_long(longlong from)=0; virtual bool store_longlong(longlong from, bool unsigned_flag)=0; virtual bool store(const char *from, uint length, CHARSET_INFO *cs)=0; + virtual bool store(const char *from, uint length, + CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0; virtual bool store(float from, uint32 decimals, String *buffer)=0; virtual bool store(double from, uint32 decimals, String *buffer)=0; virtual bool store(TIME *time)=0; @@ -97,6 +99,8 @@ public: virtual bool store_long(longlong from); virtual bool store_longlong(longlong from, bool unsigned_flag); virtual bool store(const char *from, uint length, CHARSET_INFO *cs); + virtual bool store(const char *from, uint length, + CHARSET_INFO *fromcs, CHARSET_INFO *tocs); virtual bool store(TIME *time); virtual bool store_date(TIME *time); virtual bool store_time(TIME *time); @@ -121,6 +125,8 @@ public: virtual bool store_long(longlong from); virtual bool store_longlong(longlong from, bool unsigned_flag); virtual bool store(const char *from,uint length, CHARSET_INFO *cs); + virtual bool store(const char *from, uint length, + CHARSET_INFO *fromcs, CHARSET_INFO *tocs); virtual bool store(TIME *time); virtual bool store_date(TIME *time); virtual bool store_time(TIME *time); diff --git a/sql/sql_class.h b/sql/sql_class.h index 097416985a2..9a853fc5736 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -662,6 +662,8 @@ public: DBUG_PRINT("error",("Fatal error set")); } inline CHARSET_INFO *charset() { return variables.thd_charset; } + inline CHARSET_INFO *result_charset(CHARSET_INFO *cs) + { return variables.convert_result_charset ? variables.thd_charset : cs; } }; /* |