Bug #6996 Prepared Statements: mysql_stmt_data_seek(stmt, 0) doesn't function properly
Submitted: 3 Dec 2004 18:41 Modified: 7 Dec 2004 17:24
Reporter: Timothy Smith Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:4.1.7 OS:Any (all)
Assigned to: CPU Architecture:Any

[3 Dec 2004 18:41] Timothy Smith
Description:
After several successful mysql_stmt_fetch() calls, and a successful mysql_stmt_data_seek(), another mysql_stmt_fetch() fails with MYSQL_NO_DATA.

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

int main(void)
{
  MYSQL *conn = 0;
  MYSQL_STMT *stmt = 0;
  MYSQL_RES *res = 0;
  MYSQL_BIND *bind;
  int r = 0;
  long unsigned int len;

  char *create = "CREATE TABLE qtest (a int)";
  char *insert = "INSERT INTO qtest VALUES(2),(3),(4)";
  char *drop = "DROP TABLE qtest";
  char *select = "SELECT * FROM qtest";

  conn = mysql_init((MYSQL*) 0);
  mysql_real_connect(conn, "localhost", "root", "", "test" , 3306, NULL, 0);

  mysql_real_query(conn, create, strlen(create));
  mysql_real_query(conn, insert, strlen(insert));

  stmt = mysql_stmt_init(conn);
  r = mysql_stmt_prepare(stmt, select, strlen(select));

  bind = (MYSQL_BIND*)malloc(sizeof(MYSQL_BIND));

  bind->buffer_type = MYSQL_TYPE_STRING;
  bind->buffer = (char*) malloc(sizeof(char) * 200);
  bind->buffer_length = 200;
  bind->is_null = 0;
  bind->length = &len;

  r = mysql_stmt_bind_result(stmt, bind);
  printf("Error bind: %s\n", mysql_stmt_error(stmt));

  r = mysql_stmt_execute(stmt);
  printf("Error execute: %s\n", mysql_stmt_error(stmt));
  r = mysql_stmt_store_result(stmt);
  printf("Error store result: %s\n", mysql_stmt_error(stmt));

  // retreive all result sets till we are at the end
  while(!mysql_stmt_fetch(stmt))
      printf("fetched result:%s\n", bind->buffer);

  // seek to the first row
  mysql_stmt_data_seek(stmt, 0);
  printf("Error data seek: %s\n", mysql_stmt_error(stmt));

  // now we should be able to fetch the results again
  // but mysql_stmt_fetch returns MYSQL_NO_DATA
  while(!(r = mysql_stmt_fetch(stmt)))
      printf("fetched result after seek:%s\n", bind->buffer);
  if(r == MYSQL_NO_DATA)
      printf("No Data! ):\n");

  mysql_real_query(conn, drop, strlen(drop));
  mysql_stmt_free_result(stmt);
  mysql_stmt_close(stmt);
  mysql_close(conn);

  free(bind->buffer);
  free(bind);

  return 0;
}
[7 Dec 2004 10:49] Daniel Muench
The bug is in mysql_stmt_fetch: 
There you set  
stmt->read_row_func= stmt_read_row_no_data; 
if read_row_func returns MYSQL_NO_DATA 
 
But if you have a buffered result set, there is no chance to read from it again after 
this call - even if you call mysql_stmt_data_seek() 
  
It is also marked with a /* XXX: this is buggy */ so I guess you already know where 
the failure is (:
[7 Dec 2004 17:24] MySQL Verification Team
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

ChangeSet: 1.2142 
in MySQL 4.1.8