diff options
Diffstat (limited to 'libmysql/libmysql.c')
-rw-r--r-- | libmysql/libmysql.c | 90 |
1 files changed, 47 insertions, 43 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 7a4fc9fabd4..554c3fc0ab6 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 @@ -1139,7 +1139,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); } /* @@ -1273,6 +1273,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); @@ -1524,8 +1525,8 @@ 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, 2048, MYF(MY_THREAD_SPECIFIC)); + init_alloc_root(&stmt->result.alloc, 4096, 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; @@ -1536,7 +1537,8 @@ 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); } @@ -2086,8 +2088,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; @@ -2574,7 +2576,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)); } @@ -3190,22 +3192,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: @@ -3213,9 +3217,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: @@ -3238,7 +3244,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; @@ -3337,7 +3343,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: @@ -3463,7 +3469,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); @@ -3685,7 +3691,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; @@ -3695,7 +3701,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; @@ -3706,7 +3712,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; @@ -3717,7 +3723,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); @@ -3773,7 +3779,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; @@ -3785,7 +3791,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) @@ -4614,6 +4620,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) { @@ -4678,27 +4692,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))) { @@ -4710,7 +4715,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)); } /* @@ -4730,7 +4735,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)); } /* @@ -4842,7 +4847,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; |