summaryrefslogtreecommitdiff
path: root/libmysql/libmysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmysql/libmysql.c')
-rw-r--r--libmysql/libmysql.c100
1 files changed, 57 insertions, 43 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 1df5f0b6d2c..3af4a032e5b 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates
- Copyright (c) 2009, 2014, Monty Program Ab
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1140,7 +1140,7 @@ void my_net_local_init(NET *net)
my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
net->retry_count= 1;
- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
+ net->max_packet_size= MY_MAX(net_buffer_length, max_allowed_packet);
}
/*
@@ -1274,6 +1274,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *, MYSQL_FIELD *field);
#define RESET_LONG_DATA 2
#define RESET_STORE_RESULT 4
#define RESET_CLEAR_ERROR 8
+#define RESET_ALL_BUFFERS 16
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
@@ -1507,6 +1508,12 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
memory
*/
+#ifdef EMBEDDED_LIBRARY
+#define STMT_INIT_PREALLOC(S) 0
+#else
+#define STMT_INIT_PREALLOC(S) S
+#endif /*EMBEDDED_LIBRARY*/
+
MYSQL_STMT * STDCALL
mysql_stmt_init(MYSQL *mysql)
{
@@ -1525,8 +1532,10 @@ mysql_stmt_init(MYSQL *mysql)
DBUG_RETURN(NULL);
}
- init_alloc_root(&stmt->mem_root, 2048, 2048);
- init_alloc_root(&stmt->result.alloc, 4096, 4096);
+ init_alloc_root(&stmt->mem_root, 2048, STMT_INIT_PREALLOC(2048),
+ MYF(MY_THREAD_SPECIFIC));
+ init_alloc_root(&stmt->result.alloc, 4096, STMT_INIT_PREALLOC(4096),
+ MYF(MY_THREAD_SPECIFIC));
stmt->result.alloc.min_malloc= sizeof(MYSQL_ROWS);
mysql->stmts= list_add(mysql->stmts, &stmt->list);
stmt->list.data= stmt;
@@ -1537,11 +1546,14 @@ mysql_stmt_init(MYSQL *mysql)
strmov(stmt->sqlstate, not_error_sqlstate);
/* The rest of statement members was bzeroed inside malloc */
- init_alloc_root(&stmt->extension->fields_mem_root, 2048, 0);
+ init_alloc_root(&stmt->extension->fields_mem_root, 2048, 0,
+ MYF(MY_THREAD_SPECIFIC));
DBUG_RETURN(stmt);
}
+#undef STMT_INIT_PREALLOC
+
/*
Prepare server side statement with query.
@@ -2087,8 +2099,8 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
buff[4]= (char) stmt->flags;
int4store(buff+5, 1); /* iteration count */
- res= test(cli_advanced_command(mysql, COM_STMT_EXECUTE, buff, sizeof(buff),
- (uchar*) packet, length, 1, stmt) ||
+ res= MY_TEST(cli_advanced_command(mysql, COM_STMT_EXECUTE, buff, sizeof(buff),
+ (uchar*) packet, length, 1, stmt) ||
(*mysql->methods->read_query_result)(mysql));
stmt->affected_rows= mysql->affected_rows;
stmt->server_status= mysql->server_status;
@@ -2575,7 +2587,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
reinit_result_set_metadata(stmt);
prepare_to_fetch_result(stmt);
}
- DBUG_RETURN(test(stmt->last_errno));
+ DBUG_RETURN(MY_TEST(stmt->last_errno));
}
@@ -3191,22 +3203,24 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
{
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
float fdata= (float) data;
- *param->error= (fdata != data) | test(err);
+ *param->error= (fdata != data) | MY_TEST(err);
floatstore(buffer, fdata);
break;
}
case MYSQL_TYPE_DOUBLE:
{
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
- *param->error= test(err);
+ *param->error= MY_TEST(err);
doublestore(buffer, data);
break;
}
case MYSQL_TYPE_TIME:
{
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
- str_to_time(value, length, tm, 0, &err);
- *param->error= test(err);
+ MYSQL_TIME_STATUS status;
+ str_to_time(value, length, tm, 0, &status);
+ err= status.warnings;
+ *param->error= MY_TEST(err);
break;
}
case MYSQL_TYPE_DATE:
@@ -3214,9 +3228,11 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
case MYSQL_TYPE_TIMESTAMP:
{
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
- (void) str_to_datetime(value, length, tm, 0, &err);
- *param->error= test(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
- tm->time_type != MYSQL_TIMESTAMP_DATE);
+ MYSQL_TIME_STATUS status;
+ (void) str_to_datetime(value, length, tm, 0, &status);
+ err= status.warnings;
+ *param->error= MY_TEST(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
+ tm->time_type != MYSQL_TIMESTAMP_DATE);
break;
}
case MYSQL_TYPE_TINY_BLOB:
@@ -3239,7 +3255,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
copy_length= end - start;
/* We've got some data beyond offset: copy up to buffer_length bytes */
if (param->buffer_length)
- memcpy(buffer, start, min(copy_length, param->buffer_length));
+ memcpy(buffer, start, MY_MIN(copy_length, param->buffer_length));
}
else
copy_length= 0;
@@ -3338,7 +3354,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
{
int error;
value= number_to_datetime(value, 0, (MYSQL_TIME *) buffer, 0, &error);
- *param->error= test(error);
+ *param->error= MY_TEST(error);
break;
}
default:
@@ -3464,7 +3480,7 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
size_t len;
if (field->decimals >= NOT_FIXED_DEC)
len= my_gcvt(value, type,
- (int) min(sizeof(buff)-1, param->buffer_length),
+ (int) MY_MIN(sizeof(buff)-1, param->buffer_length),
buff, NULL);
else
len= my_fcvt(value, (int) field->decimals, buff, NULL);
@@ -3686,7 +3702,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
static void fetch_result_tinyint(MYSQL_BIND *param, MYSQL_FIELD *field,
uchar **row)
{
- my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
+ my_bool field_is_unsigned= MY_TEST(field->flags & UNSIGNED_FLAG);
uchar data= **row;
*(uchar *)param->buffer= data;
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX8;
@@ -3696,7 +3712,7 @@ static void fetch_result_tinyint(MYSQL_BIND *param, MYSQL_FIELD *field,
static void fetch_result_short(MYSQL_BIND *param, MYSQL_FIELD *field,
uchar **row)
{
- my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
+ my_bool field_is_unsigned= MY_TEST(field->flags & UNSIGNED_FLAG);
ushort data= (ushort) sint2korr(*row);
shortstore(param->buffer, data);
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX16;
@@ -3707,7 +3723,7 @@ static void fetch_result_int32(MYSQL_BIND *param,
MYSQL_FIELD *field __attribute__((unused)),
uchar **row)
{
- my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
+ my_bool field_is_unsigned= MY_TEST(field->flags & UNSIGNED_FLAG);
uint32 data= (uint32) sint4korr(*row);
longstore(param->buffer, data);
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX32;
@@ -3718,7 +3734,7 @@ static void fetch_result_int64(MYSQL_BIND *param,
MYSQL_FIELD *field __attribute__((unused)),
uchar **row)
{
- my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
+ my_bool field_is_unsigned= MY_TEST(field->flags & UNSIGNED_FLAG);
ulonglong data= (ulonglong) sint8korr(*row);
*param->error= param->is_unsigned != field_is_unsigned && data > LONGLONG_MAX;
longlongstore(param->buffer, data);
@@ -3774,7 +3790,7 @@ static void fetch_result_bin(MYSQL_BIND *param,
uchar **row)
{
ulong length= net_field_length(row);
- ulong copy_length= min(length, param->buffer_length);
+ ulong copy_length= MY_MIN(length, param->buffer_length);
memcpy(param->buffer, (char *)*row, copy_length);
*param->length= length;
*param->error= copy_length < length;
@@ -3786,7 +3802,7 @@ static void fetch_result_str(MYSQL_BIND *param,
uchar **row)
{
ulong length= net_field_length(row);
- ulong copy_length= min(length, param->buffer_length);
+ ulong copy_length= MY_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)
@@ -4615,6 +4631,14 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
*mysql->unbuffered_fetch_owner= TRUE;
mysql->status= MYSQL_STATUS_READY;
}
+ if (flags & RESET_ALL_BUFFERS)
+ {
+ /* mysql_stmt_next_result will flush all pending
+ result sets
+ */
+ while (mysql_more_results(mysql) &&
+ mysql_stmt_next_result(stmt) == 0);
+ }
}
if (flags & RESET_SERVER_SIDE)
{
@@ -4679,27 +4703,18 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
{
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
/*
- Clear NET error state: if the following commands come through
- successfully, connection will still be usable for other commands.
+ Clear NET error state: if the following commands come through
+ successfully, connection will still be usable for other commands.
*/
net_clear_error(&mysql->net);
+
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
{
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
- if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
- mysql->unbuffered_fetch_owner= 0;
- if (mysql->status != MYSQL_STATUS_READY)
- {
- /*
- Flush result set of the connection. If it does not belong
- to this statement, set a warning.
- */
- (*mysql->methods->flush_use_result)(mysql, TRUE);
- if (mysql->unbuffered_fetch_owner)
- *mysql->unbuffered_fetch_owner= TRUE;
- mysql->status= MYSQL_STATUS_READY;
- }
+ if ((rc= reset_stmt_handle(stmt, RESET_ALL_BUFFERS | RESET_CLEAR_ERROR)))
+ return rc;
+
int4store(buff, stmt->stmt_id);
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
{
@@ -4711,7 +4726,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
my_free(stmt->extension);
my_free(stmt);
- DBUG_RETURN(test(rc));
+ DBUG_RETURN(MY_TEST(rc));
}
/*
@@ -4731,7 +4746,7 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
/* Reset the client and server sides of the prepared statement */
DBUG_RETURN(reset_stmt_handle(stmt,
RESET_SERVER_SIDE | RESET_LONG_DATA |
- RESET_CLEAR_ERROR));
+ RESET_ALL_BUFFERS | RESET_CLEAR_ERROR));
}
/*
@@ -4843,7 +4858,6 @@ int STDCALL mysql_next_result(MYSQL *mysql)
DBUG_RETURN(-1); /* No more results */
}
-
int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt)
{
MYSQL *mysql= stmt->mysql;