diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index ec35c238..43097b54 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -4776,13 +4776,22 @@ int STDCALL mysql_reset_connection(MYSQL *mysql) /* skip result sets */ if (mysql->status == MYSQL_STATUS_USE_RESULT || - mysql->status == MYSQL_STATUS_GET_RESULT || - mysql->status & SERVER_MORE_RESULTS_EXIST) + mysql->status == MYSQL_STATUS_GET_RESULT) { mthd_my_skip_result(mysql); - mysql->status= MYSQL_STATUS_READY; } + if (mysql->server_status & SERVER_MORE_RESULTS_EXIST) + { + while (mysql_next_result(mysql)) + { + MYSQL_RES *res= mysql_use_result(mysql); + mysql_free_result(res); + } + } + + mysql->status= MYSQL_STATUS_READY; + rc= ma_simple_command(mysql, COM_RESET_CONNECTION, 0, 0, 0, 0); if (rc && mysql->options.reconnect) { diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index d51b102c..2e1e8344 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -2618,7 +2618,14 @@ fail: stmt->mysql->methods->db_stmt_flush_unbuffered(stmt); } while(mysql_stmt_more_results(stmt)); } - stmt->state= MYSQL_STMT_INITTED; + + /* CONC-633: If prepare returned an error, we ignore error from execute */ + if (mysql_stmt_errno(stmt)) + { + my_set_error(mysql, mysql_stmt_errno(stmt), mysql_stmt_sqlstate(stmt), + mysql_stmt_error(stmt)); + stmt->state= MYSQL_STMT_INITTED; + } return 1; } diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index 7139fb34..c6472b4b 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -2256,7 +2256,43 @@ static int test_status_callback(MYSQL *my __attribute__((unused))) return OK; } +static int test_conc632(MYSQL *my __attribute__((unused))) +{ + MYSQL *mysql= mysql_init(NULL); + int rc; + + if (!my_test_connect(mysql, hostname, username, password, schema, port, socketname, CLIENT_REMEMBER_OPTIONS)) + { + diag("Connection failed. Error: %s", mysql_error(mysql)); + mysql_close(mysql); + return FAIL; + } + + rc= mysql_query(mysql, "CREATE OR REPLACE PROCEDURE conc632() " + "BEGIN " + " SELECT 1;" + " SELECT 2;" + "END"); + check_mysql_rc(rc, mysql); + + rc= mysql_query(mysql, "CALL conc632()"); + check_mysql_rc(rc, mysql); + + rc= mysql_reset_connection(mysql); + check_mysql_rc(rc, mysql); + + rc= mysql_ping(mysql); + check_mysql_rc(rc, mysql); + + rc= mysql_query(mysql, "DROP PROCEDURE conc632"); + check_mysql_rc(rc, mysql); + + mysql_close(mysql); + return OK; +} + struct my_tests_st my_tests[] = { + {"test_conc632", test_conc632, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_status_callback", test_status_callback, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_conc365", test_conc365, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_conc365_reconnect", test_conc365_reconnect, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 380f63a3..1295b0cc 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -5657,7 +5657,83 @@ static int test_conc627(MYSQL *mysql) return OK; } +static int test_conc633(MYSQL *mysql) +{ + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + MYSQL *my= mysql_init(NULL); + int ret= FAIL; + int rc; + + if (!mariadb_stmt_execute_direct(stmt, SL("SÄLECT 1"))) + { + diag("Syntax error expected"); + goto end; + } + + if (mysql_errno(mysql) != mysql_stmt_errno(stmt)) + { + diag("Different error codes. mysql_errno= %d, mysql_stmt_errno=%d", + mysql_errno(mysql), mysql_stmt_errno(stmt)); + goto end; + } + + if ((long)stmt->stmt_id != -1) + { + diag("Error: expected stmt_id=-1"); + goto end; + } + + if (!(my= test_connect(NULL))) + { + diag("Can establish connection (%s)", mysql_error(my)); + goto end; + } + + rc= mysql_query(my, "CREATE OR REPLACE TABLE conc633 (a int)"); + check_mysql_rc(rc, mysql); + + rc= mysql_query(mysql, "SET @@lock_wait_timeout=3"); + + rc= mysql_query(my, "LOCK TABLES conc633 WRITE"); + check_mysql_rc(rc, mysql); + + rc= mysql_query(mysql, "SET @@lock_wait_timeout=3"); + check_mysql_rc(rc, mysql); + + if (!mariadb_stmt_execute_direct(stmt, SL("INSERT INTO conc633 VALUES (1)"))) + { + diag("lock wait timeout error expected"); + goto end; + } + + if (stmt->state != MYSQL_STMT_PREPARED) + { + diag("Error: stmt hasn't prepared status"); + goto end; + } + + if ((long)stmt->stmt_id == -1) + { + diag("Error: no stmt_id assigned"); + goto end; + } + + rc= mysql_query(my, "UNLOCK TABLES"); + check_mysql_rc(rc, mysql); + rc= mysql_query(my, "DROP TABLE conc633"); + check_mysql_rc(rc, mysql); + + ret= OK; + +end: + if (my) + mysql_close(my); + mysql_stmt_close(stmt); + return ret; +} + struct my_tests_st my_tests[] = { + {"test_conc633", test_conc633, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc623", test_conc623, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc627", test_conc627, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_mdev19838", test_mdev19838, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},