26 #include "sql_class.h"
32 static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
36 bool net_send_ok(THD *, uint, uint, ulonglong, ulonglong,
const char *);
38 bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
39 #ifndef EMBEDDED_LIBRARY
40 static bool write_eof_packet(THD *,
NET *, uint, uint);
43 #ifndef EMBEDDED_LIBRARY
44 bool Protocol::net_store_data(
const uchar *from,
size_t length)
46 bool Protocol_binary::net_store_data(
const uchar *from,
size_t length)
49 ulong packet_length=packet->length();
54 if (packet_length+9+length > packet->alloced_length() &&
55 packet->realloc(packet_length+9+length))
57 uchar *
to= net_store_length((uchar*) packet->ptr()+packet_length, length);
58 memcpy(to,from,length);
59 packet->length((uint) (to+length-(uchar*) packet->ptr()));
78 #ifndef EMBEDDED_LIBRARY
79 bool Protocol::net_store_data(
const uchar *from,
size_t length,
85 uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
86 if (conv_length > 250)
99 return (convert->copy((
const char*) from, length, from_cs,
100 to_cs, &dummy_errors) ||
101 net_store_data((
const uchar*) convert->ptr(), convert->length()));
104 ulong packet_length= packet->length();
105 ulong new_length= packet_length + conv_length + 1;
107 if (new_length > packet->alloced_length() && packet->
realloc(new_length))
110 char *length_pos= (
char*) packet->ptr() + packet_length;
111 char *to= length_pos + 1;
113 to+= copy_and_convert(to, conv_length, to_cs,
114 (
const char*) from, length, from_cs, &dummy_errors);
116 net_store_length((uchar*) length_pos, to - length_pos - 1);
117 packet->length((uint) (to - packet->ptr()));
146 const char* sqlstate)
149 DBUG_ENTER(
"net_send_error");
151 DBUG_ASSERT(!thd->sp_runtime_ctx);
152 DBUG_ASSERT(sql_errno);
155 DBUG_PRINT(
"enter",(
"sql_errno: %d err: %s", sql_errno, err));
157 if (sqlstate == NULL)
158 sqlstate= mysql_errno_to_sqlstate(sql_errno);
164 thd->get_stmt_da()->set_overwrite_status(
true);
167 thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
171 thd->get_stmt_da()->set_overwrite_status(
false);
204 #ifndef EMBEDDED_LIBRARY
207 uint server_status, uint statement_warn_count,
208 ulonglong affected_rows, ulonglong
id,
const char *
message)
211 uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
213 DBUG_ENTER(
"net_send_ok");
217 DBUG_PRINT(
"info", (
"vio present: NO"));
222 pos=net_store_length(buff+1,affected_rows);
223 pos=net_store_length(pos,
id);
224 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
227 (
"affected_rows: %lu id: %lu status: %u warning_count: %u",
228 (ulong) affected_rows,
230 (uint) (server_status & 0xffff),
231 (uint) statement_warn_count));
232 int2store(pos, server_status);
236 uint tmp= min(statement_warn_count, 65535
U);
240 else if (net->return_status)
242 int2store(pos, server_status);
245 thd->get_stmt_da()->set_overwrite_status(
true);
247 if (message && message[0])
248 pos= net_store_data(pos, (uchar*) message, strlen(message));
254 thd->get_stmt_da()->set_overwrite_status(
false);
255 DBUG_PRINT(
"info", (
"OK sent, so no more error sending allowed"));
260 static uchar eof_buff[1]= { (uchar) 254 };
290 DBUG_ENTER(
"net_send_eof");
294 thd->get_stmt_da()->set_overwrite_status(
true);
295 error= write_eof_packet(thd, net, server_status, statement_warn_count);
298 thd->get_stmt_da()->set_overwrite_status(
false);
299 DBUG_PRINT(
"info", (
"EOF sent, so no more error sending allowed"));
320 static bool write_eof_packet(THD *thd,
NET *net,
322 uint statement_warn_count)
325 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
332 uint tmp= min(statement_warn_count, 65535
U);
334 int2store(buff+1, tmp);
340 if (thd->is_fatal_error)
341 server_status&= ~SERVER_MORE_RESULTS_EXISTS;
342 int2store(buff + 3, server_status);
362 const char* sqlstate)
371 char converted_err[MYSQL_ERRMSG_SIZE];
372 char buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
374 DBUG_ENTER(
"send_error_packet");
381 fprintf(stderr,
"ERROR: %d %s\n",sql_errno,err);
386 int2store(buff,sql_errno);
388 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
392 pos= strmov(buff+3, sqlstate);
395 convert_error_message(converted_err,
sizeof(converted_err),
396 thd->variables.character_set_results,
397 err, strlen(err), system_charset_info, &error);
399 length= (uint) (strmake(pos, converted_err, MYSQL_ERRMSG_SIZE - 1) - buff);
418 static uchar *net_store_length_fast(uchar *packet, uint length)
422 *packet=(uchar) length;
426 int2store(packet,(uint) length);
488 DBUG_ENTER(
"Protocol::end_statement");
489 DBUG_ASSERT(! thd->get_stmt_da()->is_sent());
493 if (thd->get_stmt_da()->is_sent())
496 switch (thd->get_stmt_da()->status()) {
499 error=
send_error(thd->get_stmt_da()->sql_errno(),
500 thd->get_stmt_da()->message(),
501 thd->get_stmt_da()->get_sqlstate());
505 thd->get_stmt_da()->statement_warn_count());
508 error=
send_ok(thd->server_status,
509 thd->get_stmt_da()->statement_warn_count(),
510 thd->get_stmt_da()->affected_rows(),
511 thd->get_stmt_da()->last_insert_id(),
512 thd->get_stmt_da()->message());
519 error=
send_ok(thd->server_status, 0, 0, 0, NULL);
523 thd->get_stmt_da()->set_is_sent(
true);
538 ulonglong affected_rows, ulonglong last_insert_id,
541 DBUG_ENTER(
"Protocol::send_ok");
543 net_send_ok(thd, server_status, statement_warn_count,
544 affected_rows, last_insert_id, message);
557 DBUG_ENTER(
"Protocol::send_eof");
558 const bool retval=
net_send_eof(thd, server_status, statement_warn_count);
570 const char *sql_state)
572 DBUG_ENTER(
"Protocol::send_error");
585 uchar *net_store_data(uchar *to,
const uchar *from,
size_t length)
587 to=net_store_length_fast(to,length);
588 memcpy(to,from,length);
592 uchar *net_store_data(uchar *to,int32 from)
595 uint length=(uint) (int10_to_str(from,buff,10)-buff);
596 to=net_store_length_fast(to,length);
597 memcpy(to,buff,length);
601 uchar *net_store_data(uchar *to,longlong from)
604 uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
605 to=net_store_length_fast(to,length);
606 memcpy(to,buff,length);
615 void Protocol::init(THD *thd_arg)
618 packet= &thd->packet;
619 convert= &thd->convert_buffer;
637 bool Protocol::flush()
639 #ifndef EMBEDDED_LIBRARY
641 thd->get_stmt_da()->set_overwrite_status(
true);
643 thd->get_stmt_da()->set_overwrite_status(
false);
650 #ifndef EMBEDDED_LIBRARY
674 uchar buff[MAX_FIELD_WIDTH];
675 String tmp((
char*) buff,
sizeof(buff),&my_charset_bin);
677 String *local_packet= prot.storage_packet();
678 const CHARSET_INFO *thd_charset= thd->variables.character_set_results;
679 DBUG_ENTER(
"send_result_set_metadata");
681 if (flags & SEND_NUM_ROWS)
683 uchar *pos= net_store_length(buff, list->elements);
689 field_types= (enum_field_types*) thd->alloc(
sizeof(field_types) *
699 item->make_field(&field);
702 if (field.type == MYSQL_TYPE_VARCHAR)
703 field.type= MYSQL_TYPE_VAR_STRING;
705 prot.prepare_for_resend();
707 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
709 if (prot.store(STRING_WITH_LEN(
"def"), cs, thd_charset) ||
710 prot.store(field.db_name, (uint) strlen(field.db_name),
712 prot.store(field.table_name, (uint) strlen(field.table_name),
714 prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
716 prot.store(field.col_name, (uint) strlen(field.col_name),
718 prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
720 local_packet->
realloc(local_packet->length()+12))
723 pos= (
char*) local_packet->ptr()+local_packet->length();
726 DBUG_EXECUTE_IF(
"poison_rs_fields", pos[-1]= 0xfb;);
727 if (item->charset_for_protocol() == &my_charset_bin || thd_charset == NULL)
730 int2store(pos, item->charset_for_protocol()->number);
731 int4store(pos+2, field.length);
736 uint32 field_length, max_length;
737 int2store(pos, thd_charset->number);
755 max_length= (field.type >= MYSQL_TYPE_TINY_BLOB &&
756 field.type <= MYSQL_TYPE_BLOB) ?
757 field.length / item->collation.collation->mbminlen :
758 field.length / item->collation.collation->mbmaxlen;
759 field_length= char_to_byte_length_safe(max_length,
760 thd_charset->mbmaxlen);
761 int4store(pos + 2, field_length);
764 int2store(pos+7,field.flags);
765 pos[9]= (char) field.decimals;
772 if (prot.store(field.table_name, (uint) strlen(field.table_name),
774 prot.store(field.col_name, (uint) strlen(field.col_name),
776 local_packet->
realloc(local_packet->length()+10))
778 pos= (
char*) local_packet->ptr()+local_packet->length();
780 int3store(pos+1,field.length);
784 int2store(pos+7,field.flags);
785 pos[9]= (char) field.decimals;
788 local_packet->length((uint) (pos - local_packet->ptr()));
789 if (flags & SEND_DEFAULTS)
790 item->
send(&prot, &tmp);
794 field_types[count++]= field.type;
798 if (flags & SEND_EOF)
805 if (write_eof_packet(thd, &thd->net, thd->server_status,
806 thd->get_stmt_da()->current_statement_warn_count()))
809 DBUG_RETURN(prepare_for_send(list->elements));
812 my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
818 bool Protocol::write()
820 DBUG_ENTER(
"Protocol::write");
821 DBUG_RETURN(
my_net_write(&thd->net, (uchar*) packet->ptr(),
839 char buffer[MAX_FIELD_WIDTH];
840 String str_buffer(buffer,
sizeof (buffer), &my_charset_bin);
843 DBUG_ENTER(
"Protocol::send_result_set_row");
845 for (
Item *item= it++; item; item= it++)
847 if (item->
send(
this, &str_buffer))
861 str_buffer.set(buffer,
sizeof(buffer), &my_charset_bin);
886 uint length= strlen(from);
887 return store(from, length, cs);
898 String tmp(buf,
sizeof(buf), &my_charset_bin);
909 if ((len= tmp.length()))
911 return store((
char*) tmp.ptr(), len, tmp.charset());
922 #ifndef EMBEDDED_LIBRARY
923 void Protocol_text::prepare_for_resend()
931 bool Protocol_text::store_null()
938 return packet->append(buff,
sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
953 if (tocs && !my_charset_same(fromcs, tocs) &&
954 fromcs != &my_charset_bin &&
955 tocs != &my_charset_bin)
958 return net_store_data((uchar*) from, length, fromcs, tocs);
961 return net_store_data((uchar*) from, length);
965 bool Protocol_text::store(
const char *from,
size_t length,
970 DBUG_ASSERT(field_types == 0 ||
971 field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
972 field_types[field_pos] == MYSQL_TYPE_BIT ||
973 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
974 (field_types[field_pos] >= MYSQL_TYPE_ENUM &&
975 field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
982 bool Protocol_text::store(
const char *from,
size_t length,
985 const CHARSET_INFO *tocs= this->thd->variables.character_set_results;
987 DBUG_PRINT(
"info", (
"Protocol_text::store field %u (%u): %.*s", field_pos,
988 field_count, (
int) length, (length == 0 ?
"" : from)));
989 DBUG_ASSERT(field_pos < field_count);
990 DBUG_ASSERT(field_types == 0 ||
991 field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
992 field_types[field_pos] == MYSQL_TYPE_BIT ||
993 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
994 field_types[field_pos] == MYSQL_TYPE_NEWDATE ||
995 (field_types[field_pos] >= MYSQL_TYPE_ENUM &&
996 field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
1003 bool Protocol_text::store_tiny(longlong from)
1006 DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
1010 return net_store_data((uchar*) buff,
1011 (
size_t) (int10_to_str((
int) from, buff, -10) - buff));
1015 bool Protocol_text::store_short(longlong from)
1018 DBUG_ASSERT(field_types == 0 ||
1019 field_types[field_pos] == MYSQL_TYPE_YEAR ||
1020 field_types[field_pos] == MYSQL_TYPE_SHORT);
1024 return net_store_data((uchar*) buff,
1025 (
size_t) (int10_to_str((
int) from, buff, -10) -
1030 bool Protocol_text::store_long(longlong from)
1033 DBUG_ASSERT(field_types == 0 ||
1034 field_types[field_pos] == MYSQL_TYPE_INT24 ||
1035 field_types[field_pos] == MYSQL_TYPE_LONG);
1039 return net_store_data((uchar*) buff,
1040 (
size_t) (int10_to_str((
long int)from, buff,
1041 (from <0)?-10:10)-buff));
1045 bool Protocol_text::store_longlong(longlong from,
bool unsigned_flag)
1048 DBUG_ASSERT(field_types == 0 ||
1049 field_types[field_pos] == MYSQL_TYPE_LONGLONG);
1053 return net_store_data((uchar*) buff,
1054 (
size_t) (longlong10_to_str(from,buff,
1055 unsigned_flag ? 10 : -10)-
1060 bool Protocol_text::store_decimal(
const my_decimal *d)
1063 DBUG_ASSERT(field_types == 0 ||
1064 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
1068 String str(buff,
sizeof(buff), &my_charset_bin);
1069 (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
1070 return net_store_data((uchar*) str.ptr(), str.length());
1074 bool Protocol_text::store(
float from, uint32 decimals,
String *buffer)
1077 DBUG_ASSERT(field_types == 0 ||
1078 field_types[field_pos] == MYSQL_TYPE_FLOAT);
1081 buffer->set_real((
double) from, decimals, thd->charset());
1082 return net_store_data((uchar*) buffer->ptr(), buffer->length());
1086 bool Protocol_text::store(
double from, uint32 decimals,
String *buffer)
1089 DBUG_ASSERT(field_types == 0 ||
1090 field_types[field_pos] == MYSQL_TYPE_DOUBLE);
1093 buffer->set_real(from, decimals, thd->charset());
1094 return net_store_data((uchar*) buffer->ptr(), buffer->length());
1098 bool Protocol_text::store(
Field *field)
1100 if (field->is_null())
1101 return store_null();
1105 char buff[MAX_FIELD_WIDTH];
1106 String str(buff,
sizeof(buff), &my_charset_bin);
1107 const CHARSET_INFO *tocs= this->thd->variables.character_set_results;
1110 my_bitmap_map *old_map= 0;
1112 old_map= dbug_tmp_use_all_columns(table, table->read_set);
1115 field->val_str(&str);
1118 dbug_tmp_restore_column_map(table->read_set, old_map);
1134 DBUG_ASSERT(field_types == 0 ||
1135 is_temporal_type_with_date_and_time(field_types[field_pos]));
1138 char buff[MAX_DATE_STRING_REP_LENGTH];
1139 uint length= my_datetime_to_str(tm, buff, decimals);
1140 return net_store_data((uchar*) buff, length);
1144 bool Protocol_text::store_date(
MYSQL_TIME *tm)
1147 DBUG_ASSERT(field_types == 0 ||
1148 field_types[field_pos] == MYSQL_TYPE_DATE);
1151 char buff[MAX_DATE_STRING_REP_LENGTH];
1152 size_t length= my_date_to_str(tm, buff);
1153 return net_store_data((uchar*) buff, length);
1157 bool Protocol_text::store_time(
MYSQL_TIME *tm, uint decimals)
1160 DBUG_ASSERT(field_types == 0 ||
1161 field_types[field_pos] == MYSQL_TYPE_TIME);
1164 char buff[MAX_DATE_STRING_REP_LENGTH];
1165 uint length= my_time_to_str(tm, buff, decimals);
1166 return net_store_data((uchar*) buff, length);
1182 DBUG_ASSERT(sp_params->elements ==
1183 thd->lex->prepared_stmt_params.elements);
1191 LEX_STRING *user_var_name= user_var_name_it++;
1193 if (!item_param || !user_var_name)
1205 if (suv->fix_fields(thd, NULL))
1208 if (suv->
check(FALSE))
1237 bool Protocol_binary::prepare_for_send(uint num_columns)
1239 Protocol::prepare_for_send(num_columns);
1240 bit_fields= (field_count+9)/8;
1241 return packet->alloc(bit_fields+1);
1247 void Protocol_binary::prepare_for_resend()
1249 packet->length(bit_fields+1);
1250 memset(const_cast<char*>(packet->ptr()), 0, 1+bit_fields);
1255 bool Protocol_binary::store(
const char *from,
size_t length,
1258 const CHARSET_INFO *tocs= thd->variables.character_set_results;
1263 bool Protocol_binary::store(
const char *from,
size_t length,
1271 bool Protocol_binary::store_null()
1273 uint
offset= (field_pos+2)/8+1, bit= (1 << ((field_pos+2) & 7));
1275 char *to= (
char*) packet->ptr()+
offset;
1276 *to= (char) ((uchar) *to | (uchar) bit);
1282 bool Protocol_binary::store_tiny(longlong from)
1286 buff[0]= (uchar) from;
1287 return packet->append(buff,
sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
1291 bool Protocol_binary::store_short(longlong from)
1294 char *to= packet->prep_append(2, PACKET_BUFFER_EXTRA_ALLOC);
1297 int2store(to, (
int) from);
1302 bool Protocol_binary::store_long(longlong from)
1305 char *to= packet->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC);
1308 int4store(to, from);
1313 bool Protocol_binary::store_longlong(longlong from,
bool unsigned_flag)
1316 char *to= packet->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC);
1319 int8store(to, from);
1323 bool Protocol_binary::store_decimal(
const my_decimal *d)
1326 DBUG_ASSERT(field_types == 0 ||
1327 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
1331 String str(buff,
sizeof(buff), &my_charset_bin);
1332 (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
1333 return store(str.ptr(), str.length(), str.charset());
1336 bool Protocol_binary::store(
float from, uint32 decimals,
String *buffer)
1339 char *to= packet->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC);
1342 float4store(to, from);
1347 bool Protocol_binary::store(
double from, uint32 decimals,
String *buffer)
1350 char *to= packet->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC);
1353 float8store(to, from);
1358 bool Protocol_binary::store(
Field *field)
1364 if (field->is_null())
1365 return store_null();
1366 return field->send_binary(
this);
1370 bool Protocol_binary::store(
MYSQL_TIME *tm, uint precision)
1377 int2store(pos, tm->year);
1378 pos[2]= (uchar) tm->month;
1379 pos[3]= (uchar) tm->day;
1380 pos[4]= (uchar) tm->hour;
1381 pos[5]= (uchar) tm->minute;
1382 pos[6]= (uchar) tm->second;
1386 else if (tm->hour || tm->minute || tm->second)
1388 else if (tm->year || tm->month || tm->day)
1392 buff[0]=(char) length;
1393 return packet->append(buff, length+1, PACKET_BUFFER_EXTRA_ALLOC);
1396 bool Protocol_binary::store_date(
MYSQL_TIME *tm)
1398 tm->hour= tm->minute= tm->second=0;
1400 return Protocol_binary::store(tm, 0);
1404 bool Protocol_binary::store_time(
MYSQL_TIME *tm, uint precision)
1406 char buff[13], *pos;
1410 pos[0]= tm->neg ? 1 : 0;
1414 uint days= tm->hour/24;
1418 int4store(pos+1, tm->day);
1419 pos[5]= (uchar) tm->hour;
1420 pos[6]= (uchar) tm->minute;
1421 pos[7]= (uchar) tm->second;
1425 else if (tm->hour || tm->minute || tm->second || tm->day)
1429 buff[0]=(char) length;
1430 return packet->append(buff, length+1, PACKET_BUFFER_EXTRA_ALLOC);
1445 if (!(thd->client_capabilities & CLIENT_PS_MULTI_RESULTS))
1466 if (out_param_lst.push_back(item_param))
1471 if (!out_param_lst.elements)
1479 thd->server_status|= SERVER_PS_OUT_PARAMS | SERVER_MORE_RESULTS_EXISTS;
1487 prepare_for_resend();
1496 thd->server_status&= ~SERVER_PS_OUT_PARAMS;
1502 thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;