diff options
Diffstat (limited to 'sql/protocol.cc')
-rw-r--r-- | sql/protocol.cc | 98 |
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); |