diff options
Diffstat (limited to 'libmysql/libmysql.c')
-rw-r--r-- | libmysql/libmysql.c | 100 |
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; |