Bug #9520 SELECT DISTINCT crashes server with cursor
Submitted: 31 Mar 2005 11:51 Modified: 16 May 2005 15:26
Reporter: Hakan Küçükyılmaz Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:5.0.4 OS:Linux (SuSE 9.2)
Assigned to: Konstantin Osipov CPU Architecture:Any

[31 Mar 2005 11:51] Hakan Küçükyılmaz
Description:
A "SELECT DISTINCT b from t1" crashes server when "b" is part of primary key.

How to repeat:
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>

MYSQL_STMT *stmt1;
MYSQL *mysql;

void die_if(int rc, int line, const char *msg) {
  if (rc) {
    printf("Error in line %d: %s\n", line, msg);
    exit (-1);
  }
}

MYSQL_STMT *open_cursor(char *query) {
  const unsigned long type= CURSOR_TYPE_READ_ONLY;

  MYSQL *stmt=  mysql_stmt_init(mysql);
  die_if(mysql_stmt_prepare(stmt, query, strlen(query)), __LINE__, mysql_stmt_error(stmt));
  die_if(mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type), __LINE__, mysql_stmt_error(stmt));
  return stmt;
}

int main (int argc, char **argv) {
  MYSQL_BIND bind[1];
  char a[6];
  unsigned long a_len;
  int rc;
  int cnt = 0;

  mysql= mysql_init(NULL);
  mysql_real_connect(mysql, "localhost", "root", "", "test", 0, NULL, 0);

  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)) ENGINE InnoDB");
  mysql_query(mysql, "INSERT INTO t1 VALUES ('x' , 'y', 'z')");
  mysql_query(mysql, "INSERT INTO t1 VALUES ('a' , 'b', 'c')");
  mysql_query(mysql, "INSERT INTO t1 VALUES ('k' , 'l', 'm')");

  stmt1= open_cursor("SELECT DISTINCT b FROM t1");

  /* Not crashes with:
  stmt1= open_cursor("SELECT DISTINCT a FROM t1");
  */

  die_if(mysql_stmt_execute(stmt1), __LINE__, mysql_stmt_error(stmt1));

  bind[0].buffer_type=    MYSQL_TYPE_VAR_STRING;
  bind[0].buffer=        (char *) a;
  bind[0].buffer_length= sizeof(a);
  bind[0].is_null=       0;
  bind[0].error=         NULL;
  bind[0].length=        &a_len;

  die_if(mysql_stmt_bind_result(stmt1, bind), __LINE__, mysql_stmt_error(stmt1));

  while (!(rc= mysql_stmt_fetch(stmt1))) {
    cnt++;
  }

  printf("Fetched %d rows\n", cnt);

  mysql_stmt_close(stmt1);

  mysql_close(mysql);
}

gdb outputs:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1091107168 (LWP 31686)]
0x00000000005f3c1a in Cursor::fetch (this=0x3829800, num_rows=828728321)
    at sql_select.cc:1818
1818      COND *on_expr= *join_tab->on_expr_ref;

Version info: Changeset 1.1842, BUILD/compile-amd64-debug-max
[31 Mar 2005 13:48] Miguel Solorzano
Tested on Linux and Windows:

/sql_select.cpp

int
Cursor::fetch(ulong num_rows)
{
  THD *thd= join->thd;
  JOIN_TAB *join_tab= join->join_tab + join->const_tables;
  COND *on_expr= *join_tab->on_expr_ref;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Call stack:

>	mysqld.exe!Cursor::fetch(unsigned long num_rows=1)  Line 1818 + 0x6	C++
 	mysqld.exe!mysql_stmt_fetch(THD * thd=0x00efd6a0, char * packet=0x02fb8fdd, unsigned int packet_length=9)  Line 2228	C++
 	mysqld.exe!dispatch_command(enum_server_command command=COM_FETCH, THD * thd=0x00efd6a0, char * packet=0x02fb8fd9, unsigned int packet_length=9)  Line 1617 + 0x11	C++
 	mysqld.exe!do_command(THD * thd=0x00efd6a0)  Line 1453 + 0x31	C++
 	mysqld.exe!handle_one_connection(void * arg=0x00efd6a0)  Line 1110 + 0x9	C++
 	mysqld.exe!pthread_start(void * param=0x00effbf0)  Line 63 + 0x7	C
 	mysqld.exe!_threadstart(void * ptd=0x02fb4b70)  Line 173 + 0xd	C
 	kernel32.dll!7c80b50b() 	
 	kernel32.dll!7c8399f3()
[5 Apr 2005 12:25] Konstantin Osipov
Hakan, 
while the crash itself should not be hard to fix, investigating the issue with different row count might require more time than I originally anticipated.
[17 Apr 2005 2:29] Konstantin Osipov
Date: Mon, 11 Apr 2005 22:59:14 -0700 (PDT)
Subject: bk commit - 5.0 tree (konstantin:1.1891) BUG#9520

ChangeSet
  1.1891 05/04/11 22:59:03 konstantin@mysql.com +3 -0
  A fix and a test case for Bug#9520 "SELECT DISTINCT crashes server
   with cursor" (goes on top of the previous two changesets).
[29 Apr 2005 17:56] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/internals/24488
[16 May 2005 15:26] Paul Dubois
Noted in 5.0.6 changelog.