diff --git a/libmariadb/libmariadb.c b/libmariadb/libmariadb.c index ab1ac6f5..d19d64e8 100644 --- a/libmariadb/libmariadb.c +++ b/libmariadb/libmariadb.c @@ -562,9 +562,7 @@ mthd_my_send_cmd(MYSQL *mysql,enum enum_server_command command, const char *arg, goto end; } - mysql->net.last_error[0]=0; - mysql->net.last_errno=0; - strmov(mysql->net.sqlstate, "00000"); + CLEAR_CLIENT_ERROR(mysql); mysql->info=0; mysql->affected_rows= ~(my_ulonglong) 0; diff --git a/libmariadb/my_stmt.c b/libmariadb/my_stmt.c index 08bd269a..48efc159 100644 --- a/libmariadb/my_stmt.c +++ b/libmariadb/my_stmt.c @@ -1071,7 +1071,8 @@ unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt) my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt) { - return madb_reset_stmt(stmt, MADB_RESET_LONGDATA | MADB_RESET_STORED | MADB_RESET_ERROR); + return madb_reset_stmt(stmt, MADB_RESET_LONGDATA | MADB_RESET_STORED | + MADB_RESET_BUFFER | MADB_RESET_ERROR); } MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql) @@ -1259,6 +1260,7 @@ fail: int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) { + unsigned int last_server_status; DBUG_ENTER("mysql_stmt_store_result"); if (!stmt->mysql) @@ -1281,6 +1283,8 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } + last_server_status= stmt->mysql->server_status; + /* if stmt is a cursor, we need to tell server to send all rows */ if (stmt->cursor_exists && stmt->mysql->status == MYSQL_STATUS_READY) { @@ -1308,6 +1312,15 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) stmt->mysql->status= MYSQL_STATUS_READY; DBUG_RETURN(1); } + + /* workaround for MDEV 6304: + more results not set if the resultset has + SERVER_PS_OUT_PARAMS set + */ + if (last_server_status & SERVER_PS_OUT_PARAMS && + !(stmt->mysql->server_status & SERVER_MORE_RESULTS_EXIST)) + stmt->mysql->server_status|= SERVER_MORE_RESULTS_EXIST; + stmt->result_cursor= stmt->result.data; stmt->fetch_row_func= stmt_buffered_fetch; stmt->mysql->status= MYSQL_STATUS_READY; @@ -1567,7 +1580,8 @@ static my_bool madb_reset_stmt(MYSQL_STMT *stmt, unsigned int flags) /* free buffered resultset, previously allocated * by mysql_stmt_store_result */ - if (flags & MADB_RESET_STORED) + if (flags & MADB_RESET_STORED && + stmt->result_cursor) { free_root(&stmt->result.alloc, MYF(MY_KEEP_PREALLOC)); stmt->result.data= NULL; diff --git a/libmariadb/net.c b/libmariadb/net.c index 0f1c3c00..cbe9dc96 100644 --- a/libmariadb/net.c +++ b/libmariadb/net.c @@ -173,6 +173,7 @@ static my_bool net_realloc(NET *net, size_t length) DBUG_RETURN(0); } +#if defined(DBUG_OFF) || defined(USE_NET_CLEAR) static int net_check_if_data_available(Vio *vio) { my_socket sd= vio->sd; @@ -189,17 +190,18 @@ static int net_check_if_data_available(Vio *vio) return 0; return FD_ISSET(sd, &sockset); } +#endif /* Remove unwanted characters from connection */ void net_clear(NET *net) { +#if defined(DBUG_OFF) || defined(USE_NET_CLEAR) int available= 0; size_t count; /* One may get 'unused' warning */ bool is_blocking=vio_is_blocking(net->vio); DBUG_ENTER("net_clear"); - while ((available= net_check_if_data_available(net->vio)) > 0) { if ((count= vio_read(net->vio, (char *)net->buff, net->max_packet))) @@ -230,6 +232,9 @@ void net_clear(NET *net) vio_blocking(net->vio, TRUE); } } +#else + DBUG_ENTER("net_clear"); +#endif net->pkt_nr=0; /* Ready for new command */ net->write_pos=net->buff; DBUG_VOID_RETURN; diff --git a/unittest/libmariadb/basic-t.c b/unittest/libmariadb/basic-t.c index 44cbb4c1..8446fe2a 100644 --- a/unittest/libmariadb/basic-t.c +++ b/unittest/libmariadb/basic-t.c @@ -476,7 +476,62 @@ static int test_extended_init_values(MYSQL *my) return OK; } +static int test_reconnect_maxpackage(MYSQL *my) +{ + int rc; + ulong max_packet= 0; + MYSQL *mysql= mysql_init(NULL); + MYSQL_RES *res; + MYSQL_ROW row; + char *query; + + FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema, + port, socketname, + CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql)); + mysql->reconnect= 1; + + rc= mysql_query(mysql, "SELECT @@max_allowed_packet"); + check_mysql_rc(rc, mysql); + res= mysql_store_result(mysql); + row= mysql_fetch_row(res); + max_packet= atol(row[0]); + diag("max_allowed_packet=%d", max_packet); + mysql_free_result(res); + + query= (char *)malloc(max_packet + 30); + memset(query, 0, max_packet); + + strcpy(query, "SELECT '"); + memset(query + 8, 'A', max_packet); + strcat(query, "' FROM DUAL"); + + + rc= mysql_query(mysql, query); + free(query); + if (!rc) + { + diag("expected error"); + mysql_close(mysql); + return FAIL; + } + else + diag("Error: %s", mysql_error(mysql)); + + rc= mysql_query(mysql, "SELECT @@max_allowed_packet"); + check_mysql_rc(rc, mysql); + res= mysql_store_result(mysql); + row= mysql_fetch_row(res); + max_packet= atol(row[0]); + diag("max_allowed_packet=%d", max_packet); + mysql_free_result(res); + + + mysql_close(mysql); + return OK; +} + struct my_tests_st my_tests[] = { + {"test_reconnect_maxpackage", test_reconnect_maxpackage, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0, opt_utf8, NULL}, {"client_query", client_query, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},