summaryrefslogtreecommitdiff
path: root/sql/protocol.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/protocol.cc')
-rw-r--r--sql/protocol.cc98
1 files changed, 50 insertions, 48 deletions
diff --git a/sql/protocol.cc b/sql/protocol.cc
index d00ecb5dbc4..7abbf3ce85b 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -52,7 +52,7 @@ void send_error(THD *thd, uint sql_errno, const char *err)
{
#ifndef EMBEDDED_LIBRARY
uint length;
- char buff[MYSQL_ERRMSG_SIZE+2];
+ char buff[MYSQL_ERRMSG_SIZE+2], *pos;
#endif
NET *net= &thd->net;
DBUG_ENTER("send_error");
@@ -98,7 +98,14 @@ void send_error(THD *thd, uint sql_errno, const char *err)
if (net->return_errno)
{ // new client code; Add errno before message
int2store(buff,sql_errno);
- length= (uint) (strmake(buff+2,err,MYSQL_ERRMSG_SIZE-1) - buff);
+ pos= buff+2;
+ if (thd->client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ /* The first # is to make the protocol backward compatible */
+ strmov(buff+2, "#000000");
+ pos= buff + 2 + SQLSTATE_LENGTH +1;
+ }
+ length= (uint) (strmake(pos, err, MYSQL_ERRMSG_SIZE-1) - buff);
err=buff;
}
else
@@ -113,26 +120,6 @@ void send_error(THD *thd, uint sql_errno, const char *err)
DBUG_VOID_RETURN;
}
-/*
- Send an error to the client when a connection is forced close
- This is used by mysqld.cc, which doesn't have a THD
-*/
-
-#ifndef EMBEDDED_LIBRARY
-void net_send_error(NET *net, uint sql_errno, const char *err)
-{
- char buff[2];
- uint length;
- DBUG_ENTER("send_net_error");
-
- int2store(buff,sql_errno);
- length=(uint) strlen(err);
- set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
- net_write_command(net,(uchar) 255, buff, 2, err, length);
- DBUG_VOID_RETURN;
-}
-#endif
-
/*
Send a warning to the end user
@@ -173,7 +160,7 @@ net_printf(THD *thd, uint errcode, ...)
#ifndef EMBEDDED_LIBRARY
const char *text_pos;
#else
- char text_pos[500];
+ char text_pos[1024];
#endif
int head_length= NET_HEADER_SIZE;
NET *net= &thd->net;
@@ -199,9 +186,11 @@ net_printf(THD *thd, uint errcode, ...)
format=va_arg(args,char*);
errcode= ER_UNKNOWN_ERROR;
}
- offset= net->return_errno ? 2 : 0;
+ offset= (net->return_errno ?
+ ((thd->client_capabilities & CLIENT_PROTOCOL_41) ?
+ 2+SQLSTATE_LENGTH+1 : 2) : 0);
#ifndef EMBEDDED_LIBRARY
- text_pos=(char*) net->buff+head_length+offset+1;
+ text_pos=(char*) net->buff + head_length + offset + 1;
#endif
(void) vsprintf(my_const_cast(char*) (text_pos),format,args);
length=(uint) strlen((char*) text_pos);
@@ -228,7 +217,15 @@ net_printf(THD *thd, uint errcode, ...)
net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
net->buff[head_length]=(uchar) 255; // Error package
if (offset)
- int2store(text_pos-2, errcode);
+ {
+ uchar *pos= net->buff+head_length+1;
+ int2store(pos, errcode);
+ if (thd->client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ /* The first # is to make the protocol backward compatible */
+ memcpy(pos+2, "#000000", SQLSTATE_LENGTH +1);
+ }
+ }
VOID(net_real_write(net,(char*) net->buff,length+head_length+1+offset));
#else
net->last_errno= errcode;
@@ -502,6 +499,7 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
Protocol_simple prot(thd);
String *packet= prot.storage_packet();
+ CHARSET_INFO *thd_charset= thd->variables.character_set_results;
DBUG_ENTER("send_fields");
if (flag & 1)
@@ -526,36 +524,37 @@ 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, thd->charset()) ||
+ if (prot.store("std", 3, cs, thd_charset) ||
+ 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()) ||
+ cs, thd_charset) ||
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
- cs, thd->charset()) ||
+ cs, thd_charset) ||
prot.store(field.col_name, (uint) strlen(field.col_name),
- cs, thd->charset()) ||
+ cs, thd_charset) ||
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
- cs, thd->charset()) ||
+ cs, thd_charset) ||
packet->realloc(packet->length()+12))
goto err;
/* Store fixed length fields */
pos= (char*) packet->ptr()+packet->length();
- *pos++= 11; // Length of packed fields
+ *pos++= 12; // Length of packed fields
int2store(pos, field.charsetnr);
- int3store(pos+2, field.length);
- pos[5]= field.type;
- int2store(pos+6,field.flags);
- pos[8]= (char) field.decimals;
- pos[9]= 0; // For the future
+ int4store(pos+2, field.length);
+ pos[6]= field.type;
+ int2store(pos+7,field.flags);
+ pos[9]= (char) field.decimals;
pos[10]= 0; // For the future
- pos+= 11;
+ pos[11]= 0; // For the future
+ pos+= 12;
}
else
{
if (prot.store(field.table_name, (uint) strlen(field.table_name),
- cs, thd->charset()) ||
+ cs, thd_charset) ||
prot.store(field.col_name, (uint) strlen(field.col_name),
- cs, thd->charset()) ||
+ cs, thd_charset) ||
packet->realloc(packet->length()+10))
goto err;
pos= (char*) packet->ptr()+packet->length();
@@ -709,7 +708,7 @@ bool Protocol_simple::store(const char *from, uint length,
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
field_pos++;
#endif
- if (!my_charset_same(fromcs, tocs) &&
+ if (tocs && !my_charset_same(fromcs, tocs) &&
(fromcs != &my_charset_bin) &&
(tocs != &my_charset_bin))
{
@@ -724,7 +723,7 @@ bool Protocol_simple::store(const char *from, uint length,
bool Protocol_simple::store(const char *from, uint length,
CHARSET_INFO *fromcs)
{
- CHARSET_INFO *tocs= this->thd->variables.collation_results;
+ CHARSET_INFO *tocs= this->thd->variables.character_set_results;
#ifndef DEBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
@@ -732,7 +731,7 @@ bool Protocol_simple::store(const char *from, uint length,
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
field_pos++;
#endif
- if (!my_charset_same(fromcs, tocs) &&
+ if (tocs && !my_charset_same(fromcs, tocs) &&
(fromcs != &my_charset_bin) &&
(tocs != &my_charset_bin))
{
@@ -831,12 +830,14 @@ bool Protocol_simple::store(Field *field)
#endif
char buff[MAX_FIELD_WIDTH];
String str(buff,sizeof(buff), &my_charset_bin);
+ CHARSET_INFO *tocs= this->thd->variables.character_set_results;
+
field->val_str(&str,&str);
- if (!my_charset_same(field->charset(), this->thd->charset()) &&
+ if (tocs && !my_charset_same(field->charset(), tocs) &&
(field->charset() != &my_charset_bin) &&
- (this->thd->charset() != &my_charset_bin))
+ (tocs != &my_charset_bin))
{
- convert.copy(str.ptr(), str.length(), str.charset(), this->thd->charset());
+ convert.copy(str.ptr(), str.length(), str.charset(), tocs);
return net_store_data(convert.ptr(), convert.length());
}
else
@@ -891,9 +892,10 @@ bool Protocol_simple::store_time(TIME *tm)
#endif
char buff[40];
uint length;
+ uint day= (tm->year || tm->month) ? 0 : tm->day;
length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
tm->neg ? "-" : "",
- (long) tm->day*3600L+(long) tm->hour,
+ (long) day*24L+(long) tm->hour,
(int) tm->minute,
(int) tm->second));
return net_store_data((char*) buff, length);