Loading sql/sql_prepare.cc +1 −1 Original line number Diff line number Diff line Loading @@ -2223,7 +2223,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) my_pthread_setprio(pthread_self(), QUERY_PRIOR); thd->protocol= &thd->protocol_prep; // Switch to binary protocol (void) stmt->cursor->fetch(num_rows); stmt->cursor->fetch(num_rows); thd->protocol= &thd->protocol_simple; // Use normal protocol if (!(specialflag & SPECIAL_NO_PRIOR)) Loading sql/sql_select.cc +381 −353 File changed.Preview size limit exceeded, changes collapsed. Show changes sql/sql_select.h +16 −2 Original line number Diff line number Diff line Loading @@ -91,7 +91,15 @@ enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF, class JOIN; typedef int (*Next_select_func)(JOIN *,struct st_join_table *,bool); enum enum_nested_loop_state { NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1, NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1, NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4 }; typedef enum_nested_loop_state (*Next_select_func)(JOIN *, struct st_join_table *, bool); typedef int (*Read_record_func)(struct st_join_table *tab); Loading Loading @@ -162,6 +170,11 @@ class JOIN :public Sql_alloc uint send_group_parts; bool sort_and_group,first_record,full_join,group, no_field_update; bool do_send_rows; /* TRUE when we want to resume nested loop iterations when fetching data from a cursor */ bool resume_nested_loop; table_map const_table_map,found_const_table_map,outer_join; ha_rows send_records,found_records,examined_rows,row_limit, select_limit; /* Loading Loading @@ -263,6 +276,7 @@ class JOIN :public Sql_alloc sort_and_group= 0; first_record= 0; do_send_rows= 1; resume_nested_loop= FALSE; send_records= 0; found_records= 0; fetch_limit= HA_POS_ERROR; Loading Loading @@ -374,7 +388,7 @@ class Cursor: public Sql_alloc, public Item_arena void reset_thd(THD *thd); int open(JOIN *join); int fetch(ulong num_rows); void fetch(ulong num_rows); void reset() { join= 0; } bool is_open() const { return join != 0; } void close(); Loading tests/mysql_client_test.c +54 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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 } }; Loading Loading
sql/sql_prepare.cc +1 −1 Original line number Diff line number Diff line Loading @@ -2223,7 +2223,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) my_pthread_setprio(pthread_self(), QUERY_PRIOR); thd->protocol= &thd->protocol_prep; // Switch to binary protocol (void) stmt->cursor->fetch(num_rows); stmt->cursor->fetch(num_rows); thd->protocol= &thd->protocol_simple; // Use normal protocol if (!(specialflag & SPECIAL_NO_PRIOR)) Loading
sql/sql_select.cc +381 −353 File changed.Preview size limit exceeded, changes collapsed. Show changes
sql/sql_select.h +16 −2 Original line number Diff line number Diff line Loading @@ -91,7 +91,15 @@ enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF, class JOIN; typedef int (*Next_select_func)(JOIN *,struct st_join_table *,bool); enum enum_nested_loop_state { NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1, NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1, NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4 }; typedef enum_nested_loop_state (*Next_select_func)(JOIN *, struct st_join_table *, bool); typedef int (*Read_record_func)(struct st_join_table *tab); Loading Loading @@ -162,6 +170,11 @@ class JOIN :public Sql_alloc uint send_group_parts; bool sort_and_group,first_record,full_join,group, no_field_update; bool do_send_rows; /* TRUE when we want to resume nested loop iterations when fetching data from a cursor */ bool resume_nested_loop; table_map const_table_map,found_const_table_map,outer_join; ha_rows send_records,found_records,examined_rows,row_limit, select_limit; /* Loading Loading @@ -263,6 +276,7 @@ class JOIN :public Sql_alloc sort_and_group= 0; first_record= 0; do_send_rows= 1; resume_nested_loop= FALSE; send_records= 0; found_records= 0; fetch_limit= HA_POS_ERROR; Loading Loading @@ -374,7 +388,7 @@ class Cursor: public Sql_alloc, public Item_arena void reset_thd(THD *thd); int open(JOIN *join); int fetch(ulong num_rows); void fetch(ulong num_rows); void reset() { join= 0; } bool is_open() const { return join != 0; } void close(); Loading
tests/mysql_client_test.c +54 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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 } }; Loading