summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/protocol.cc71
-rw-r--r--sql/protocol.h6
-rw-r--r--sql/sql_class.h2
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; }
};
/*