summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2005-08-10 18:36:13 +0400
committerunknown <konstantin@mysql.com>2005-08-10 18:36:13 +0400
commit21239c9f314acd958e41062081e80ecb62747433 (patch)
tree456848ab2f200b91bb21ed69d717cf36187eabdc /tests
parent689f32a19448bfd57eeadf0945d90575b74d2b52 (diff)
downloadmariadb-git-21239c9f314acd958e41062081e80ecb62747433.tar.gz
A fix and a test case for Bug#12243 "MySQL Server crashes with 2
cursors (+ commit)" and Bug#11832 "Server crash with InnoDB + Cursors" See comments to the changed files. innobase/include/read0read.h: - add cursor_view_t::n_mysql_tables_in_use innobase/read/read0read.c: - maintain cursor_view_t::n_mysql_tables_in_use. InnoDB maintains trx->n_mysql_tables_in_use to know when it can auto-commit a read-only statement. When this count drops to zero, MySQL has ended processing of such statement and InnoDB can commit. Cursors should not break this invariant, and should exclude the tables used in a cursor from the count of active tables. When a cursor is closed, the number of its tables is added back, to ensure that close_thread_tables->unlock_external-> ha_innobase::external_lock(F_UNLCK) won't drop the count in trx below zero. innobase/row/row0sel.c: - remove the restoration of the global read view from row_search_for_mysql: MySQL may call row_search_for_mysql more than once when fetching a row for a cursor (e.g. if there is a WHERE clause that filters out some rows). sql/ha_innodb.cc: - add more verbose printout for the case when we close an InnoDB connection without priorlly issuing a commit or rollback. The problem should be investigated. tests/mysql_client_test.c: - add a test case for Bug#12243 "MySQL Server crashes with 2 cursors (+ commit)"
Diffstat (limited to 'tests')
-rw-r--r--tests/mysql_client_test.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 15cba906f6b..75f57436c38 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14179,6 +14179,66 @@ static void test_bug11901()
myquery(rc);
}
+/* Bug#12243: multiple cursors, crash in a fetch after commit. */
+
+static void test_bug12243()
+{
+ MYSQL_STMT *stmt1, *stmt2;
+ int rc;
+ const char *stmt_text;
+ ulong type;
+
+ myheader("test_bug12243");
+
+ if (! have_innodb)
+ {
+ if (!opt_silent)
+ printf("This test requires InnoDB.\n");
+ return;
+ }
+
+ /* create tables */
+ mysql_query(mysql, "drop table if exists t1");
+ mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
+ rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
+ myquery(rc);
+ mysql_autocommit(mysql, FALSE);
+ /* create statement */
+ stmt1= mysql_stmt_init(mysql);
+ stmt2= mysql_stmt_init(mysql);
+ type= (ulong) CURSOR_TYPE_READ_ONLY;
+ mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
+ mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
+
+ stmt_text= "select a from t1";
+
+ rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
+ check_execute(stmt1, rc);
+ rc= mysql_stmt_execute(stmt1);
+ check_execute(stmt1, rc);
+ rc= mysql_stmt_fetch(stmt1);
+ check_execute(stmt1, rc);
+
+ rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
+ check_execute(stmt2, rc);
+ rc= mysql_stmt_execute(stmt2);
+ check_execute(stmt2, rc);
+ rc= mysql_stmt_fetch(stmt2);
+ check_execute(stmt2, rc);
+
+ rc= mysql_stmt_close(stmt1);
+ check_execute(stmt1, rc);
+ rc= mysql_commit(mysql);
+ myquery(rc);
+ rc= mysql_stmt_fetch(stmt2);
+ check_execute(stmt2, rc);
+
+ mysql_stmt_close(stmt2);
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+ mysql_autocommit(mysql, TRUE); /* restore default */
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -14427,6 +14487,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug12001", test_bug12001 },
{ "test_bug11909", test_bug11909 },
{ "test_bug11901", test_bug11901 },
+ { "test_bug12243", test_bug12243 },
{ 0, 0 }
};