summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/mysql_client_test.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 20284924c6c..76d0ab2e4cc 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -55,6 +55,7 @@ static char current_db[]= "client_test_db";
static unsigned int test_count= 0;
static unsigned int opt_count= 0;
static unsigned int iter_count= 0;
+static my_bool have_innodb= FALSE;
static const char *opt_basedir= "./";
@@ -220,6 +221,28 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
}
}
+/* Check if the connection has InnoDB tables */
+
+static my_bool check_have_innodb(MYSQL *conn)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int rc;
+ my_bool result;
+
+ rc= mysql_query(conn, "show variables like 'have_innodb'");
+ myquery(rc);
+ res= mysql_use_result(conn);
+ DIE_UNLESS(res);
+
+ row= mysql_fetch_row(res);
+ DIE_UNLESS(row);
+
+ result= strcmp(row[1], "YES") == 0;
+ mysql_free_result(res);
+ return result;
+}
+
/*
This is to be what mysql_query() is for mysql_real_query(), for
@@ -290,6 +313,7 @@ static void client_connect(ulong flag)
strxmov(query, "USE ", current_db, NullS);
rc= mysql_query(mysql, query);
myquery(rc);
+ have_innodb= check_have_innodb(mysql);
if (!opt_silent)
fprintf(stdout, " OK");
@@ -13757,6 +13781,110 @@ static void test_bug11037()
myquery(rc);
}
+/* Bug#10760: cursors, crash in a fetch after rollback. */
+
+static void test_bug10760()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[1];
+ int rc;
+ const char *stmt_text;
+ char id_buf[20];
+ ulong id_len;
+ int i= 0;
+ ulong type;
+
+ myheader("test_bug10760");
+
+ mysql_query(mysql, "drop table if exists t1, t2");
+
+ /* create tables */
+ rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
+ " engine=MyISAM");
+ myquery(rc);
+ for (; i < 42; ++i)
+ {
+ char buf[100];
+ sprintf(buf, "insert into t1 (id) values (%d)", i+1);
+ rc= mysql_query(mysql, buf);
+ myquery(rc);
+ }
+ mysql_autocommit(mysql, FALSE);
+ /* create statement */
+ stmt= mysql_stmt_init(mysql);
+ type= (ulong) CURSOR_TYPE_READ_ONLY;
+ mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
+
+ /*
+ 1: check that a deadlock within the same connection
+ is resolved and an error is returned. The deadlock is modelled
+ as follows:
+ con1: open cursor for select * from t1;
+ con1: insert into t1 (id) values (1)
+ */
+ stmt_text= "select id from t1 order by 1";
+ rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+ check_execute(stmt, rc);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ rc= mysql_query(mysql, "update t1 set id=id+100");
+ DIE_UNLESS(rc);
+ if (!opt_silent)
+ printf("Got error (as expected): %s\n", mysql_error(mysql));
+ /*
+ 2: check that MyISAM tables used in cursors survive
+ COMMIT/ROLLBACK.
+ */
+ rc= mysql_rollback(mysql); /* should not close the cursor */
+ myquery(rc);
+ rc= mysql_stmt_fetch(stmt);
+ check_execute(stmt, rc);
+
+ /*
+ 3: check that cursors to InnoDB tables are closed (for now) by
+ COMMIT/ROLLBACK.
+ */
+ if (! have_innodb)
+ {
+ if (!opt_silent)
+ printf("Testing that cursors are closed at COMMIT/ROLLBACK requires "
+ "InnoDB.\n");
+ }
+ else
+ {
+ stmt_text= "select id from t1 order by 1";
+ rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+ check_execute(stmt, rc);
+
+ rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
+ myquery(rc);
+
+ bzero(bind, sizeof(bind));
+ bind[0].buffer_type= MYSQL_TYPE_STRING;
+ bind[0].buffer= (void*) id_buf;
+ bind[0].buffer_length= sizeof(id_buf);
+ bind[0].length= &id_len;
+ check_execute(stmt, rc);
+ mysql_stmt_bind_result(stmt, bind);
+
+ rc= mysql_stmt_execute(stmt);
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == 0);
+ if (!opt_silent)
+ printf("Fetched row %s\n", id_buf);
+ rc= mysql_rollback(mysql); /* should close the cursor */
+ myquery(rc);
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc);
+ if (!opt_silent)
+ printf("Got error (as expected): %s\n", mysql_error(mysql));
+ }
+
+ mysql_stmt_close(stmt);
+ 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
@@ -14002,6 +14130,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug9735", test_bug9735 },
{ "test_bug11183", test_bug11183 },
{ "test_bug11037", test_bug11037 },
+ { "test_bug10760", test_bug10760 },
{ 0, 0 }
};