1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

A fix and a test case for Bug#9520 "SELECT DISTINCT crashes server

with cursor". The patch refactors do_select/sub_select
functions, which implement the nested loop algorithm, and reuses them to
fetch rows for cursors as well.
Pushing with view.test failing (--ps-protocol).


sql/sql_prepare.cc:
   Cursor::fetch() now returns void
sql/sql_select.cc:
  A fix for Bug#9520 "SELECT DISTINCT crashes server with cursor":
  * rename sub_select returns codes to be able to track down what's going
    on in which case.
  * move record processing and outer join record processing to a separate
    function, out of sub_select read-record loop.
  * use generalized sub_select() nested loop function for
  cursors instead of own loop implementation used in Cursor::fetch() before
sql/sql_select.h:
  Replace all return values of sub_select family with enum.
  Add JOIN::resume_nested_loop flag to indicate we are restarting the nested loop
  for execution of next chunk of cursor's rows.
tests/mysql_client_test.c:
  A test case for Bug#9520 "SELECT DISTINCT crashes server with cursor"
This commit is contained in:
unknown
2005-04-30 09:54:35 +04:00
parent e9cc39c43f
commit 963e94ce49
4 changed files with 456 additions and 360 deletions

View File

@ -12854,6 +12854,59 @@ static void test_bug9159()
myquery(rc);
}
/* Crash when opening a cursor to a query with DISTICNT and no key */
static void test_bug9520()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
char a[6];
ulong a_len;
int rc, row_count= 0;
myheader("test_bug9520");
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
" primary key (a, b, c))");
rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
" ('a', 'b', 'c'), ('k', 'l', 'm')");
myquery(rc);
stmt= open_cursor("select distinct b from t1");
/*
Not crashes with:
stmt= open_cursor("select distinct a from t1");
*/
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
bzero(bind, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (char*) a;
bind[0].buffer_length= sizeof(a);
bind[0].length= &a_len;
mysql_stmt_bind_result(stmt, bind);
while (!(rc= mysql_stmt_fetch(stmt)))
row_count++;
DIE_UNLESS(rc == MYSQL_NO_DATA);
printf("Fetched %d rows\n", row_count);
DBUG_ASSERT(row_count == 3);
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
@ -13079,6 +13132,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug8722", test_bug8722 },
{ "test_bug8880", test_bug8880 },
{ "test_bug9159", test_bug9159 },
{ "test_bug9520", test_bug9520 },
{ 0, 0 }
};