summaryrefslogtreecommitdiff
path: root/libmysql/libmysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmysql/libmysql.c')
-rw-r--r--libmysql/libmysql.c511
1 files changed, 348 insertions, 163 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 3e31f254913..2b97f6b90e4 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -115,7 +115,6 @@ static sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list);
-static unsigned int get_binary_length(uint type);
static my_bool org_my_init_done=0;
@@ -3952,6 +3951,27 @@ mysql_prepare_result(MYSQL_STMT *stmt)
DBUG_RETURN(result);
}
+/*
+ Returns parameter columns meta information in the form of
+ resultset.
+*/
+
+MYSQL_RES * STDCALL
+mysql_param_result(MYSQL_STMT *stmt)
+{
+ DBUG_ENTER("mysql_param_result");
+
+ if (!stmt->param_count)
+ DBUG_RETURN(0);
+
+ /*
+ TODO: Fix this when server sends the information.
+ Till then keep a dummy prototype
+ */
+ DBUG_RETURN(0);
+}
+
+
/********************************************************************
Prepare-execute, and param handling
@@ -4056,9 +4076,74 @@ static void store_param_double(NET *net, MYSQL_BIND *param)
net->write_pos+= 8;
}
+static void store_param_time(NET *net, MYSQL_BIND *param)
+{
+ MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
+ char buff[15], *pos;
+ uint length;
+
+ pos= buff+1;
+ pos[0]= tm->neg ? 1: 0;
+ int4store(pos+1, tm->day);
+ pos[5]= (uchar) tm->hour;
+ pos[6]= (uchar) tm->minute;
+ pos[7]= (uchar) tm->second;
+ int4store(pos+8, tm->second_part);
+ if (tm->second_part)
+ length= 11;
+ else if (tm->hour || tm->minute || tm->second || tm->day)
+ length= 8;
+ else
+ length= 0;
+ buff[0]= (char) length++;
+ memcpy((char *)net->write_pos, buff, length);
+ net->write_pos+= length;
+}
+
+static void net_store_datetime(NET *net, MYSQL_TIME *tm)
+{
+ char buff[12], *pos;
+ uint length;
+
+ pos= buff+1;
+
+ int2store(pos, tm->year);
+ pos[2]= (uchar) tm->month;
+ pos[3]= (uchar) tm->day;
+ pos[4]= (uchar) tm->hour;
+ pos[5]= (uchar) tm->minute;
+ pos[6]= (uchar) tm->second;
+ int4store(pos+7, tm->second_part);
+ if (tm->second_part)
+ length= 11;
+ else if (tm->hour || tm->minute || tm->second)
+ length= 7;
+ else if (tm->year || tm->month || tm->day)
+ length= 4;
+ else
+ length= 0;
+ buff[0]= (char) length++;
+ memcpy((char *)net->write_pos, buff, length);
+ net->write_pos+= length;
+}
+
+static void store_param_date(NET *net, MYSQL_BIND *param)
+{
+ MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
+ tm->hour= tm->minute= tm->second= 0;
+ tm->second_part= 0;
+ net_store_datetime(net, tm);
+}
+
+static void store_param_datetime(NET *net, MYSQL_BIND *param)
+{
+ MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
+ net_store_datetime(net, tm);
+}
+
static void store_param_str(NET *net, MYSQL_BIND *param)
{
- ulong length= *param->length;
+ ulong length= min(*param->length, param->buffer_length);
char *to= (char *) net_store_length((char *) net->write_pos, length);
memcpy(to, param->buffer, length);
net->write_pos= (uchar*) to+length;
@@ -4107,10 +4192,13 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
{
/*
Param->length should ALWAYS point to the correct length for the type
- Either to the length pointer given by the user or param->bind_length
+ Either to the length pointer given by the user or param->buffer_length
*/
if ((my_realloc_str(net, 9 + *param->length)))
+ {
+ set_stmt_error(stmt, CR_OUT_OF_MEMORY);
DBUG_RETURN(1);
+ }
(*param->store_param_func)(net, param);
}
DBUG_RETURN(0);
@@ -4277,12 +4365,14 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
param++)
{
param->param_number= count++;
+ param->long_data_used= 0;
+
/*
- If param->length is not given, change it to point to bind_length.
+ If param->length is not given, change it to point to buffer_length.
This way we can always use *param->length to get the length of data
*/
if (!param->length)
- param->length= &param->bind_length;
+ param->length= &param->buffer_length;
/* If param->is_null is not set, then the value can never be NULL */
if (!param->is_null)
@@ -4295,42 +4385,52 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
break;
case MYSQL_TYPE_TINY:
/* Force param->length as this is fixed for this type */
- param->length= &param->bind_length;
- param->bind_length= param->buffer_length= 1;
+ param->length= &param->buffer_length;
+ param->buffer_length= 1;
param->store_param_func= store_param_tinyint;
break;
case MYSQL_TYPE_SHORT:
- param->length= &param->bind_length;
- param->bind_length= param->buffer_length= 2;
+ param->length= &param->buffer_length;
+ param->buffer_length= 2;
param->store_param_func= store_param_short;
break;
case MYSQL_TYPE_LONG:
- param->length= &param->bind_length;
- param->bind_length= param->buffer_length= 4;
+ param->length= &param->buffer_length;
+ param->buffer_length= 4;
param->store_param_func= store_param_int32;
break;
case MYSQL_TYPE_LONGLONG:
- param->length= &param->bind_length;
- param->bind_length= param->buffer_length= 8;
+ param->length= &param->buffer_length;
+ param->buffer_length= 8;
param->store_param_func= store_param_int64;
break;
case MYSQL_TYPE_FLOAT:
- param->length= &param->bind_length;
- param->bind_length= param->buffer_length= 4;
+ param->length= &param->buffer_length;
+ param->buffer_length= 4;
param->store_param_func= store_param_float;
break;
case MYSQL_TYPE_DOUBLE:
- param->length= &param->bind_length;
- param->bind_length= param->buffer_length= 8;
+ param->length= &param->buffer_length;
+ param->buffer_length= 8;
param->store_param_func= store_param_double;
break;
+ case MYSQL_TYPE_TIME:
+ /* Buffer length ignored for DATE, TIME and DATETIME */
+ param->store_param_func= store_param_time;
+ break;
+ case MYSQL_TYPE_DATE:
+ param->store_param_func= store_param_date;
+ break;
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ param->store_param_func= store_param_datetime;
+ break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
- param->bind_length= param->buffer_length;
param->store_param_func= store_param_str;
break;
default:
@@ -4440,24 +4540,91 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
1 Error (Can't alloc net->buffer)
****************************************************************************/
-/* Return the default binary data length for the common types */
-static unsigned int get_binary_length(uint type)
+static void set_zero_time(MYSQL_TIME *tm)
{
- switch(type) {
- case MYSQL_TYPE_TINY:
- return 1;
- case MYSQL_TYPE_SHORT:
- case MYSQL_TYPE_YEAR:
- return 2;
- case MYSQL_TYPE_LONG:
- case MYSQL_TYPE_FLOAT:
- return 4;
- case MYSQL_TYPE_LONGLONG:
- case MYSQL_TYPE_DOUBLE:
- return 8;
- default:
+ tm->year= tm->month= tm->day= 0;
+ tm->hour= tm->minute= tm->second= 0;
+ tm->second_part= 0;
+ tm->neg= (bool)0;
+}
+
+/* Read TIME from binary packet and return it to MYSQL_TIME */
+static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
+{
+ uchar *to;
+ uint length;
+
+ if (!(length= net_field_length(pos)))
+ {
+ set_zero_time(tm);
return 0;
}
+
+ to= *pos;
+ tm->second_part= (length > 8 ) ? (ulong) sint4korr(to+7): 0;
+
+ tm->day= (ulong) sint4korr(to+1);
+ tm->hour= (uint) to[5];
+ tm->minute= (uint) to[6];
+ tm->second= (uint) to[7];
+
+ tm->year= tm->month= 0;
+ tm->neg= (bool)to[0];
+ return length;
+}
+
+/* Read DATETIME from binary packet and return it to MYSQL_TIME */
+static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
+{
+ uchar *to;
+ uint length;
+
+ if (!(length= net_field_length(pos)))
+ {
+ set_zero_time(tm);
+ return 0;
+ }
+
+ to= *pos;
+ tm->second_part= (length > 7 ) ? (ulong) sint4korr(to+7): 0;
+
+ if (length > 4)
+ {
+ tm->hour= (uint) to[4];
+ tm->minute= (uint) to[5];
+ tm->second= (uint) to[6];
+ }
+ else
+ tm->hour= tm->minute= tm->second= 0;
+
+ tm->year= (uint) sint2korr(to);
+ tm->month= (uint) to[2];
+ tm->day= (uint) to[3];
+ tm->neg= 0;
+ return length;
+}
+
+/* Read DATE from binary packet and return it to MYSQL_TIME */
+static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
+{
+ uchar *to;
+ uint length;
+
+ if (!(length= net_field_length(pos)))
+ {
+ set_zero_time(tm);
+ return 0;
+ }
+
+ to= *pos;
+ tm->year = (uint) sint2korr(to);
+ tm->month= (uint) to[2];
+ tm->day= (uint) to[3];
+
+ tm->hour= tm->minute= tm->second= 0;
+ tm->second_part= 0;
+ tm->neg= 0;
+ return length;
}
/* Convert Numeric to buffer types */
@@ -4492,13 +4659,14 @@ static void send_data_long(MYSQL_BIND *param, longlong value)
}
default:
{
- uint length= sprintf(buffer,"%lld",value);
+ uint length= (uint)(longlong10_to_str(value,buffer,10)-buffer);
*param->length= length;
buffer[length]='\0';
}
}
}
+
/* Convert Double to buffer types */
static void send_data_double(MYSQL_BIND *param, double value)
{
@@ -4531,7 +4699,7 @@ static void send_data_double(MYSQL_BIND *param, double value)
}
default:
{
- uint length= sprintf(buffer,"%g",value);
+ uint length= my_sprintf(buffer,(buffer,"%g",value));
*param->length= length;
buffer[length]='\0';
}
@@ -4586,25 +4754,79 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
}
default:
*param->length= length;
+ length= min(length, param->buffer_length);
memcpy(buffer, value, length);
- buffer[length]='\0';
+ if (length != param->buffer_length)
+ buffer[length]='\0';
}
}
+static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime,
+ uint length)
+{
+ switch (param->buffer_type) {
+
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ {
+ MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
+
+ tm->year= ltime.year;
+ tm->month= ltime.month;
+ tm->day= ltime.day;
+
+ tm->hour= ltime.hour;
+ tm->minute= ltime.minute;
+ tm->second= ltime.second;
+
+ tm->second_part= ltime.second_part;
+ tm->neg= ltime.neg;
+ break;
+ }
+ default:
+ {
+ char buff[25];
+
+ if (!length)
+ ltime.time_type= MYSQL_TIMESTAMP_NONE;
+ switch (ltime.time_type) {
+ case MYSQL_TIMESTAMP_DATE:
+ length= my_sprintf(buff,(buff, "%04d-%02d-%02d", ltime.year,
+ ltime.month,ltime.day));
+ break;
+ case MYSQL_TIMESTAMP_FULL:
+ length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
+ ltime.year,ltime.month,ltime.day,
+ ltime.hour,ltime.minute,ltime.second));
+ break;
+ case MYSQL_TIMESTAMP_TIME:
+ length= my_sprintf(buff, (buff, "%02d:%02d:%02d",
+ ltime.hour,ltime.minute,ltime.second));
+ break;
+ default:
+ length= 0;
+ buff[0]='\0';
+ }
+ send_data_str(param, (char *)buff, length);
+ }
+ }
+}
+
+
/* Fetch data to buffers */
-static my_bool fetch_results(MYSQL_STMT *stmt, MYSQL_BIND *param,
- uint field_type, uchar **row)
+static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row)
{
ulong length;
- length= (ulong)get_binary_length(field_type);
-
switch (field_type) {
case MYSQL_TYPE_TINY:
{
uchar value= (uchar) **row;
send_data_long(param,(longlong)value);
+ length= 1;
break;
}
case MYSQL_TYPE_SHORT:
@@ -4612,18 +4834,21 @@ static my_bool fetch_results(MYSQL_STMT *stmt, MYSQL_BIND *param,
{
short value= (short)sint2korr(*row);
send_data_long(param,(longlong)value);
+ length= 2;
break;
}
case MYSQL_TYPE_LONG:
{
int32 value= (int32)sint4korr(*row);
send_data_long(param,(int32)value);
+ length= 4;
break;
}
case MYSQL_TYPE_LONGLONG:
{
longlong value= (longlong)sint8korr(*row);
send_data_long(param,value);
+ length= 8;
break;
}
case MYSQL_TYPE_FLOAT:
@@ -4631,6 +4856,7 @@ static my_bool fetch_results(MYSQL_STMT *stmt, MYSQL_BIND *param,
float value;
float4get(value,*row);
send_data_double(param,(double)value);
+ length= 4;
break;
}
case MYSQL_TYPE_DOUBLE:
@@ -4638,115 +4864,35 @@ static my_bool fetch_results(MYSQL_STMT *stmt, MYSQL_BIND *param,
double value;
float8get(value,*row);
send_data_double(param,(double)value);
+ length= 8;
break;
}
case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_TIMESTAMP:
{
- uchar month,day;
- short year;
- int arg_length;
- char ts[50],frac[10],time[20],date[20];
-
- if (!(length= net_field_length(row)))
- {
- *param->length= 0;
- break;
- }
- if (param->buffer_type < MYSQL_TYPE_VAR_STRING ||
- param->buffer_type > MYSQL_TYPE_STRING)
- {
- /*
- Don't allow fetching of date/time/ts to non-string types
- TODO: Allow fetching of date or time to long types.
- */
- sprintf(stmt->last_error,
- ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
- param->buffer_type, param->param_number);
- return 1;
- }
-
- arg_length= 0;
- if (length > 7)
- {
- int sec_part= sint4korr(*row+7);
- sprintf(frac,".%04d", sec_part);
- arg_length+= 5;
- }
- if (length == 7)
- {
- uchar hour, minute, sec;
- hour= *(*row+4);
- minute= *(*row+5);
- sec= *(*row+6);
- sprintf((char *)time," %02d:%02d:%02d",hour,minute,sec);
- arg_length+= 9;
- }
-
- year= sint2korr(*row);
- month= *(*row+2);
- day= *(*row+3);
- sprintf((char*) date,"%04d-%02d-%02d",year,month,day);
- arg_length+= 10;
-
- if (arg_length != 19)
- time[0]='\0';
- if (arg_length != 24)
- frac[0]='\0';
-
- strxmov(ts,date,time,frac,NullS);
- send_data_str(param,ts,arg_length);
+ MYSQL_TIME tm;
+
+ length= read_binary_date(&tm,row);
+ tm.time_type= MYSQL_TIMESTAMP_DATE;
+ send_data_time(param, tm, length);
break;
}
case MYSQL_TYPE_TIME:
{
- int day, arg_length;
- uchar hour, minute, sec;
- char ts[255], frac[20], time[20];
- const char *sign= "";
-
- if (!(length= net_field_length(row)))
- {
- *param->length= 0;
- break;
- }
- if (param->buffer_type < MYSQL_TYPE_VAR_STRING ||
- param->buffer_type > MYSQL_TYPE_STRING)
- {
- /*
- Don't allow fetching of date/time/ts to non-string types
-
- TODO: Allow fetching of time to long types without
- any conversion.
- */
- sprintf(stmt->last_error,
- ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
- param->buffer_type, param->param_number);
- return 1;
- }
- arg_length= 0;
- if (length > 8)
- {
- int sec_part= sint4korr(*row+8);
- sprintf(frac,".%04d", sec_part);
- arg_length+= 5;
- }
-
- if (**row)
- sign="-";
-
- day= sint4korr(*row); /* TODO: how to handle this case */
- hour= *(*row+5);
- minute= *(*row+6);
- sec= *(*row+7);
- arg_length+= sprintf((char *)time,"%s%02d:%02d:%02d",sign,hour,minute,sec);
-
- if (arg_length <= 9)
- frac[0]='\0';
-
- strxmov(ts,time,frac,NullS);
- send_data_str(param,ts,arg_length);
+ MYSQL_TIME tm;
+
+ length= read_binary_time(&tm, row);
+ tm.time_type= MYSQL_TIMESTAMP_TIME;
+ send_data_time(param, tm, length);
+ break;
+ }
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ {
+ MYSQL_TIME tm;
+
+ length= read_binary_datetime(&tm, row);
+ tm.time_type= MYSQL_TIMESTAMP_FULL;
+ send_data_time(param, tm, length);
break;
}
default:
@@ -4755,7 +4901,6 @@ static my_bool fetch_results(MYSQL_STMT *stmt, MYSQL_BIND *param,
break;
}
*row+= length;
- return 0;
}
static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row)
@@ -4801,12 +4946,33 @@ static void fetch_result_double(MYSQL_BIND *param, uchar **row)
*row+= 8;
}
+static void fetch_result_time(MYSQL_BIND *param, uchar **row)
+{
+ MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
+ *row+= read_binary_time(tm, row);
+}
+
+static void fetch_result_date(MYSQL_BIND *param, uchar **row)
+{
+ MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
+ *row+= read_binary_date(tm, row);
+}
+
+static void fetch_result_datetime(MYSQL_BIND *param, uchar **row)
+{
+ MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
+ *row+= read_binary_datetime(tm, row);
+}
+
static void fetch_result_str(MYSQL_BIND *param, uchar **row)
{
ulong length= net_field_length(row);
- memcpy(param->buffer, (char *)*row, length);
- *(param->buffer+length)= '\0';
- *param->length= length;
+ ulong copy_length= min(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+ *(param->buffer+copy_length)= '\0';
+ *param->length= length; // return total length
*row+= length;
}
@@ -4846,25 +5012,47 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
if (!param->is_null)
param->is_null= &int_is_null_dummy;
+ if (!param->length)
+ param->length= &param->buffer_length;
+
/* Setup data copy functions for the different supported types */
switch (param->buffer_type) {
case MYSQL_TYPE_TINY:
param->fetch_result= fetch_result_tinyint;
+ *param->length= 1;
break;
case MYSQL_TYPE_SHORT:
param->fetch_result= fetch_result_short;
+ *param->length= 2;
break;
case MYSQL_TYPE_LONG:
param->fetch_result= fetch_result_int32;
+ *param->length= 4;
break;
case MYSQL_TYPE_LONGLONG:
param->fetch_result= fetch_result_int64;
+ *param->length= 8;
break;
case MYSQL_TYPE_FLOAT:
param->fetch_result= fetch_result_float;
+ *param->length= 4;
break;
case MYSQL_TYPE_DOUBLE:
param->fetch_result= fetch_result_double;
+ *param->length= 8;
+ break;
+ case MYSQL_TYPE_TIME:
+ param->fetch_result= fetch_result_time;
+ *param->length= sizeof(MYSQL_TIME);
+ break;
+ case MYSQL_TYPE_DATE:
+ param->fetch_result= fetch_result_date;
+ *param->length= sizeof(MYSQL_TIME);
+ break;
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ param->fetch_result= fetch_result_datetime;
+ *param->length= sizeof(MYSQL_TIME);
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
@@ -4881,9 +5069,6 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
param->buffer_type, param->param_number);
DBUG_RETURN(1);
}
- if (!param->length)
- param->length= &param->bind_length;
- *param->length= (long)get_binary_length(param->buffer_type);
}
stmt->res_buffers= 1;
DBUG_RETURN(0);
@@ -4920,8 +5105,8 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
*bind->is_null= 0;
if (field->type == bind->buffer_type)
(*bind->fetch_result)(bind, &row);
- else if (fetch_results(stmt, bind, field->type, &row))
- return 1;
+ else
+ fetch_results(bind, field->type, &row);
}
if (! ((bit<<=1) & 255))
{
@@ -5052,7 +5237,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
{
MYSQL *mysql= stmt->mysql;
MYSQL_RES *result;
- DBUG_ENTER("mysql_stmt_tore_result");
+ DBUG_ENTER("mysql_stmt_store_result");
mysql= mysql->last_used_con;
@@ -5060,9 +5245,8 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
{
- strmov(mysql->net.last_error,
- ER(mysql->net.last_errno= CR_COMMANDS_OUT_OF_SYNC));
- DBUG_RETURN(0);
+ set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC);
+ DBUG_RETURN(1);
}
mysql->status= MYSQL_STATUS_READY; /* server is ready */
if (!(result= (MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
@@ -5070,8 +5254,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
stmt->field_count),
MYF(MY_WME | MY_ZEROFILL))))
{
- mysql->net.last_errno= CR_OUT_OF_MEMORY;
- strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ set_stmt_error(stmt, CR_OUT_OF_MEMORY);
DBUG_RETURN(1);
}
stmt->result_buffered= 1;
@@ -5106,7 +5289,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
*/
static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
{
- my_bool error=0;
+ my_bool error= 0;
DBUG_ENTER("mysql_stmt_close");
DBUG_ASSERT(stmt != 0);
@@ -5116,12 +5299,14 @@ static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
int4store(buff, stmt->stmt_id);
error= simple_command(stmt->mysql, COM_CLOSE_STMT, buff, 4, 1);
}
- mysql_free_result(stmt->result);
- free_root(&stmt->mem_root, MYF(0));
- my_free((gptr) stmt->query, MYF(MY_WME | MY_ALLOW_ZERO_PTR));
- if (!skip_list)
- stmt->mysql->stmts= list_delete(stmt->mysql->stmts, &stmt->list);
- my_free((gptr) stmt, MYF(MY_WME));
+ if (!error)
+ {
+ mysql_free_result(stmt->result);
+ free_root(&stmt->mem_root, MYF(0));
+ if (!skip_list)
+ stmt->mysql->stmts= list_delete(stmt->mysql->stmts, &stmt->list);
+ my_free((gptr) stmt, MYF(MY_WME));
+ }
DBUG_RETURN(error);
}