From fef3e4ed6d60f0a4fd14a08e8902d30db0215f1d Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Sat, 23 Mar 2024 12:53:24 +0100 Subject: [PATCH] CONC-683: Check pending results when closing statement. Similiar to fix for CONC-667 we need to check if other statements have a pending result set before we can close a statement handle. --- libmariadb/mariadb_stmt.c | 30 +++++++++++++++++++++++------- unittest/libmariadb/ps_bugs.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index 92f1869c..594d149f 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -123,6 +123,20 @@ void stmt_set_error(MYSQL_STMT *stmt, return; } +/* checks if there are any other statements which have a + pending result set */ +static my_bool madb_have_pending_results(MYSQL_STMT *stmt) +{ + LIST *li_stmt= stmt->mysql->stmts; + for (;li_stmt;li_stmt= li_stmt->next) + { + MYSQL_STMT *s= (MYSQL_STMT *)li_stmt->data; + if (s != stmt && s->state == MYSQL_STMT_WAITING_USE_OR_STORE) + return 1; + } + return 0; +} + my_bool mthd_supported_buffer_type(enum enum_field_types type) { switch (type) { @@ -1489,6 +1503,12 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt) { my_bool rc= 1; + if (madb_have_pending_results(stmt)) + { + stmt_set_error(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0); + return 1; + } + if (stmt) { if (stmt->mysql && stmt->mysql->net.pvio) @@ -2208,14 +2228,10 @@ static my_bool madb_reset_stmt(MYSQL_STMT *stmt, unsigned int flags) /* CONC-667: If an other statement has a pending result set, we need to return an error */ - for (;li_stmt;li_stmt= li_stmt->next) + if (madb_have_pending_results(stmt)) { - MYSQL_STMT *s= (MYSQL_STMT *)li_stmt->data; - if (s != stmt && s->state == MYSQL_STMT_WAITING_USE_OR_STORE) - { - stmt_set_error(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0); - return 1; - } + stmt_set_error(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0); + return 1; } if (!stmt->mysql) diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 562ea3ff..0623f088 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -5780,7 +5780,37 @@ static int test_conc667(MYSQL *mysql) return OK; } +static int test_conc683(MYSQL *mysql) +{ + MYSQL_STMT *stmt1, *stmt2; + int rc; + + stmt1= mysql_stmt_init(mysql); + stmt2= mysql_stmt_init(mysql); + + rc= mysql_stmt_prepare(stmt1, "SELECT 1 UNION SELECT 2", -1); + check_stmt_rc(rc, stmt1); + + rc= mysql_stmt_prepare(stmt2, "SELECT 1", -1); + check_stmt_rc(rc, stmt2); + + rc= mysql_stmt_execute(stmt1); + check_stmt_rc(rc, stmt1); + + rc= mysql_stmt_close(stmt2); + FAIL_IF(!rc || mysql_stmt_errno(stmt2) != CR_COMMANDS_OUT_OF_SYNC, + "Expected commands out of sync error"); + + rc= mysql_stmt_close(stmt1); + check_stmt_rc(rc, stmt1); + rc= mysql_stmt_close(stmt2); + check_stmt_rc(rc, stmt2); + + return OK; +} + struct my_tests_st my_tests[] = { + {"test_conc683", test_conc683, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc667", test_conc667, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc633", test_conc633, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc623", test_conc623, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},