Commit 6d74f5b0 authored by unknown's avatar unknown

fix for bug #11904 (select statement, cursor, grouping wrong results)


sql/sql_select.cc:
  reset the group functions and copy the values of the first row before exiting because of
  maximal number of rows has been read for this cursor fetch. the additional variable is needed
  to save code duplication.
tests/mysql_client_test.c:
  test for bug #11904 (cursor grouping wrong result)
parent b224e52c
...@@ -10256,6 +10256,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -10256,6 +10256,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records) bool end_of_records)
{ {
int idx= -1; int idx= -1;
enum_nested_loop_state ok_code= NESTED_LOOP_OK;
DBUG_ENTER("end_send_group"); DBUG_ENTER("end_send_group");
if (!join->first_record || end_of_records || if (!join->first_record || end_of_records ||
...@@ -10320,7 +10321,11 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -10320,7 +10321,11 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
There is a server side cursor and all rows There is a server side cursor and all rows
for this fetch request are sent. for this fetch request are sent.
*/ */
DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT); /*
Preventing code duplication. When finished with the group reset
the group functions and copy_fields. We fall through. bug #11904
*/
ok_code= NESTED_LOOP_CURSOR_LIMIT;
} }
} }
} }
...@@ -10333,12 +10338,16 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -10333,12 +10338,16 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
} }
if (idx < (int) join->send_group_parts) if (idx < (int) join->send_group_parts)
{ {
/*
This branch is executed also for cursors which have finished their
fetch limit - the reason for ok_code.
*/
copy_fields(&join->tmp_table_param); copy_fields(&join->tmp_table_param);
if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
DBUG_RETURN(NESTED_LOOP_ERROR); DBUG_RETURN(NESTED_LOOP_ERROR);
if (join->procedure) if (join->procedure)
join->procedure->add(); join->procedure->add();
DBUG_RETURN(NESTED_LOOP_OK); DBUG_RETURN(ok_code);
} }
} }
if (update_sum_func(join->sum_funcs)) if (update_sum_func(join->sum_funcs))
......
...@@ -14179,6 +14179,81 @@ static void test_bug11901() ...@@ -14179,6 +14179,81 @@ static void test_bug11901()
myquery(rc); myquery(rc);
} }
/* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
static void test_bug11904()
{
MYSQL_STMT *stmt1;
int rc;
const char *stmt_text;
const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
MYSQL_BIND bind[2];
int country_id=0;
char row_data[11]= {0};
myheader("test_bug11904");
/* create tables */
rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
" (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
" (3,'berlin'), (3, 'frankfurt')");
myquery(rc);
mysql_commit(mysql);
/* create statement */
stmt1= mysql_stmt_init(mysql);
mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
check_execute(stmt1, rc);
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer=& country_id;
bind[0].buffer_length= 0;
bind[0].length= 0;
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer=& row_data;
bind[1].buffer_length= sizeof(row_data) - 1;
bind[1].length= 0;
rc= mysql_stmt_bind_result(stmt1, bind);
check_execute(stmt1, rc);
rc= mysql_stmt_execute(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
DIE_UNLESS(country_id == 1);
DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
DIE_UNLESS(country_id == 2);
DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
DIE_UNLESS(country_id == 3);
DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
rc= mysql_stmt_close(stmt1);
check_execute(stmt1, rc);
rc= mysql_query(mysql, "drop table bug11904b");
myquery(rc);
}
/* Bug#12243: multiple cursors, crash in a fetch after commit. */ /* Bug#12243: multiple cursors, crash in a fetch after commit. */
static void test_bug12243() static void test_bug12243()
...@@ -14487,6 +14562,7 @@ static struct my_tests_st my_tests[]= { ...@@ -14487,6 +14562,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug12001", test_bug12001 }, { "test_bug12001", test_bug12001 },
{ "test_bug11909", test_bug11909 }, { "test_bug11909", test_bug11909 },
{ "test_bug11901", test_bug11901 }, { "test_bug11901", test_bug11901 },
{ "test_bug11904", test_bug11904 },
{ "test_bug12243", test_bug12243 }, { "test_bug12243", test_bug12243 },
{ 0, 0 } { 0, 0 }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment