diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index c29b60745..a51027031 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -656,6 +656,10 @@ add_test_executable(mxs1804_long_ps_hang.cpp mxs1804_long_ps_hang replication LA # https://jira.mariadb.org/browse/MXS-1808 add_test_executable(mxs1808_long_data.cpp mxs1808_long_data replication LABELS readwritesplit REPL_BACKEND) +# MXS-1824: Debug assertion with two open cursors +# https://jira.mariadb.org/browse/MXS-1824 +add_test_executable(mxs1824_double_cursor.cpp mxs1824_double_cursor replication LABELS readwritesplit REPL_BACKEND) + # 'namedserverfilter' test add_test_executable(namedserverfilter.cpp namedserverfilter namedserverfilter LABELS namedserverfilter LIGHT REPL_BACKEND) diff --git a/maxscale-system-test/mxs1824_double_cursor.cpp b/maxscale-system-test/mxs1824_double_cursor.cpp new file mode 100644 index 000000000..01d5e9020 --- /dev/null +++ b/maxscale-system-test/mxs1824_double_cursor.cpp @@ -0,0 +1,66 @@ +/** + * MXS-1824: Debug assertion with two open cursors + * + * https://jira.mariadb.org/browse/MXS-1824 + */ + +#include "testconnections.h" + +void double_cursor(TestConnections& test, MYSQL* conn) +{ + test.try_query(conn, "CREATE OR REPLACE TABLE test.t1(id int)"); + test.try_query(conn, "INSERT INTO test.t1 VALUES (1), (2), (3)"); + + test.repl->connect(); + test.repl->sync_slaves(); + test.repl->disconnect(); + + MYSQL_STMT* stmt1 = mysql_stmt_init(conn); + const char* query = "SELECT id FROM test.t1"; + int rc = mysql_stmt_prepare(stmt1, query, strlen(query)); + test.assert(rc == 0, "Prepare should work: %s %s", mysql_stmt_error(stmt1), mysql_error(conn)); + int type = CURSOR_TYPE_READ_ONLY; + mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, &type); + + MYSQL_BIND bind[1] {}; + uint32_t id; + bind[0].buffer_type = MYSQL_TYPE_LONG; + bind[0].buffer = &id; + mysql_stmt_bind_result(stmt1, bind); + + test.assert(mysql_stmt_execute(stmt1) == 0, "Execute of first statement should work: %s %s", + mysql_stmt_error(stmt1), mysql_error(conn)); + test.assert(mysql_stmt_fetch(stmt1) == 0, "First fetch should work: %s %s", + mysql_stmt_error(stmt1), mysql_error(conn)); + + MYSQL_STMT* stmt2 = mysql_stmt_init(conn); + rc = mysql_stmt_prepare(stmt2, query, strlen(query)); + test.assert(rc == 0, "Prepare should work: %s %s", mysql_stmt_error(stmt2), mysql_error(conn)); + mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, &type); + mysql_stmt_bind_result(stmt2, bind); + + test.assert(mysql_stmt_execute(stmt2) == 0, "Execute of second statement should work: %s %s", + mysql_stmt_error(stmt2), mysql_error(conn)); + test.assert(mysql_stmt_fetch(stmt2) == 0, "Second fetch should work: %s %s", mysql_stmt_error(stmt2), + mysql_error(conn)); + mysql_stmt_reset(stmt2); + + test.assert(mysql_stmt_fetch(stmt1) == 0, "Third fetch should work: %s %s", mysql_stmt_error(stmt1), + mysql_error(conn)); + + mysql_stmt_close(stmt1); + mysql_stmt_close(stmt2); + + test.try_query(conn, "DROP TABLE test.t1"); +} + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + + test.maxscales->connect(); + double_cursor(test, test.maxscales->conn_rwsplit[0]); + test.maxscales->disconnect(); + + return test.global_result; +}