List:Internals« Previous MessageNext Message »
From:konstantin Date:May 16 2005 4:27pm
Subject:bk commit into 5.0 tree (konstantin:1.1946) BUG#9643
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1946 05/05/16 18:27:21 konstantin@stripped +5 -0
  A fix and a test case for Bug#9643 " CURSOR_TYPE_SCROLLABLE dos not work"
  - check on the client the unsupported feature and return 
  an error message if it's been requested.
  Additionally added API support for STMT_ATTR_PREFETCH_ROWS.
  Post-review fixes.

  tests/mysql_client_test.c
    1.117 05/05/16 18:27:15 konstantin@stripped +63 -0
    A test case for Bug#9643 "CURSOR_TYPE_SCROLLABLE dos not work"
    - check that an error message is returned for CURSOR_TYPE_SCROLLABLE.
    Additionally, check setting of STMT_ATTR_PREFETCH_ROWS.

  libmysql/libmysql.c
    1.213 05/05/16 18:27:15 konstantin@stripped +33 -7
    Implement support for STMT_ATTR_PREFETCH_ROWS
    Return an error message on attempt to set an attribute of a prepared
    statement which is not implemented yet. We probably should be doing
    it in the server: currently the server just ignores unknown attributes.

  libmysql/errmsg.c
    1.36 05/05/16 18:27:14 konstantin@stripped +3 -0
    Text for the error message CR_NOT_IMPLEMENTED

  include/mysql.h
    1.149 05/05/16 18:27:14 konstantin@stripped +7 -1
    Add a statement attribute STMT_ATTR_PREFETCH_ROWS - unsigned long
    number of rows to fetch per one COM_FETCH command, used when there
    is a read-only cursor.
    Note, that we don't break compatibility by adding this new member
    because MYSQL_STMT is always allocated inside the client library by
    mysql_stmt_init.

  include/errmsg.h
    1.27 05/05/16 18:27:14 konstantin@stripped +2 -1
    Add a new error code for "Not implemented" client-side error message.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	konstantin
# Host:	dragonfly.local
# Root:	/opt/local/work/mysql-5.0-9643

--- 1.26/include/errmsg.h	2005-05-12 11:16:06 +04:00
+++ 1.27/include/errmsg.h	2005-05-16 18:27:14 +04:00
@@ -96,6 +96,7 @@
 #define CR_NO_DATA                              2051
 #define CR_NO_STMT_METADATA                     2052
 #define CR_NO_RESULT_SET                        2053
-#define CR_ERROR_LAST  /*Copy last error nr:*/  2053
+#define CR_NOT_IMPLEMENTED                      2054
+#define CR_ERROR_LAST  /*Copy last error nr:*/  2054
 /* Add error numbers before CR_ERROR_LAST and change it accordingly. */
 

--- 1.148/include/mysql.h	2005-04-13 14:22:15 +04:00
+++ 1.149/include/mysql.h	2005-05-16 18:27:14 +04:00
@@ -663,6 +663,7 @@
                                   unsigned char **row);
   unsigned long	 stmt_id;	       /* Id for prepared statement */
   unsigned long  flags;                /* i.e. type of cursor to open */
+  unsigned long  prefetch_rows;        /* number of rows per one COM_FETCH */
   /*
     Copied from mysql->server_status after execute/fetch to know
     server-side cursor status for this statement.
@@ -701,7 +702,12 @@
     unsigned long with combination of cursor flags (read only, for update,
     etc)
   */
-  STMT_ATTR_CURSOR_TYPE
+  STMT_ATTR_CURSOR_TYPE,
+  /*
+    Amount of rows to retrieve from server per one fetch if using cursors.
+    Accepts unsigned long attribute in the range 1 - ulong_max
+  */
+  STMT_ATTR_PREFETCH_ROWS
 };
 
 

--- 1.35/libmysql/errmsg.c	2005-05-13 19:14:58 +04:00
+++ 1.36/libmysql/errmsg.c	2005-05-16 18:27:14 +04:00
@@ -81,6 +81,7 @@
   "Attempt to read column without prior row fetch",
   "Prepared statement contains no metadata",
   "Attempt to read a row while there is no result set associated with the statement",
+  "This feature is not implemented yet",
   ""
 };
 
@@ -143,6 +144,7 @@
   "Attempt to read column without prior row fetch",
   "Prepared statement contains no metadata",
   "Attempt to read a row while there is no result set associated with the statement",
+  "This feature is not implemented yet",
   ""
 };
 
@@ -203,6 +205,7 @@
   "Attempt to read column without prior row fetch",
   "Prepared statement contains no metadata",
   "Attempt to read a row while there is no result set associated with the statement",
+  "This feature is not implemented yet",
   ""
 };
 #endif

--- 1.212/libmysql/libmysql.c	2005-05-12 11:16:07 +04:00
+++ 1.213/libmysql/libmysql.c	2005-05-16 18:27:15 +04:00
@@ -1703,6 +1703,9 @@
 
 /******************* Declarations ***********************************/
 
+/* Default number of rows fetched per one COM_FETCH command. */
+
+#define DEFAULT_PREFETCH_ROWS 1UL
 
 /*
   These functions are called by function pointer MYSQL_STMT::read_row_func.
@@ -1728,6 +1731,7 @@
 
 #define RESET_SERVER_SIDE 1
 #define RESET_LONG_DATA 2
+#define RESET_STORE_RESULT 4
 
 static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
 
@@ -1968,6 +1972,7 @@
   stmt->state= MYSQL_STMT_INIT_DONE;
   stmt->mysql= mysql;
   stmt->read_row_func= stmt_read_row_no_data;
+  stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
   /* The rest of statement members was bzeroed inside malloc */
 
   DBUG_RETURN(stmt);
@@ -2026,7 +2031,7 @@
     /* This is second prepare with another statement */
     char buff[MYSQL_STMT_HEADER];               /* 4 bytes - stmt id */
 
-    if (reset_stmt_handle(stmt, RESET_LONG_DATA))
+    if (reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT))
       DBUG_RETURN(1);
     /*
       These members must be reset for API to
@@ -2681,7 +2686,7 @@
     result->rows= 0;
     /* Send row request to the server */
     int4store(buff, stmt->stmt_id);
-    int4store(buff + 4, 1); /* number of rows to fetch */
+    int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
     if (cli_advanced_command(mysql, COM_FETCH, buff, sizeof(buff),
                              NullS, 0, 1))
     {
@@ -2739,12 +2744,29 @@
     stmt->update_max_length= value ? *(const my_bool*) value : 0;
     break;
   case STMT_ATTR_CURSOR_TYPE:
-    stmt->flags= value ? *(const unsigned long *) value : 0;
+  {
+    ulong cursor_type;
+    cursor_type= value ? *(ulong*) value : 0UL;
+    if (cursor_type > (ulong) CURSOR_TYPE_READ_ONLY)
+      goto err_not_implemented;
+    stmt->flags= cursor_type;
+    break;
+  }
+  case STMT_ATTR_PREFETCH_ROWS:
+  {
+    ulong prefetch_rows= value ? *(ulong*) value : DEFAULT_PREFETCH_ROWS;
+    if (value == 0)
+      return TRUE;
+    stmt->prefetch_rows= prefetch_rows;
     break;
+  }
   default:
-    return TRUE;
+    goto err_not_implemented;
   }
   return FALSE;
+err_not_implemented:
+  set_stmt_error(stmt, CR_NOT_IMPLEMENTED, unknown_sqlstate);
+  return TRUE;
 }
 
 
@@ -2821,7 +2843,7 @@
     DBUG_RETURN(1);
   }
 
-  if (reset_stmt_handle(stmt, 0))
+  if (reset_stmt_handle(stmt, RESET_STORE_RESULT))
     DBUG_RETURN(1);
   /*
     No need to check for stmt->state: if the statement wasn't
@@ -4826,7 +4848,11 @@
     MYSQL_DATA *result= &stmt->result;
     my_bool has_cursor= stmt->read_row_func == stmt_read_row_from_cursor;
 
-    if (result->data)
+    /*
+      Reset stored result set if so was requested or it's a part
+      of cursor fetch.
+    */
+    if (result->data && (has_cursor || (flags & RESET_STORE_RESULT)))
     {
       /* Result buffered */
       free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
@@ -4885,7 +4911,7 @@
   DBUG_ENTER("mysql_stmt_free_result");
 
   /* Free the client side and close the server side cursor if there is one */
-  DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA));
+  DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT));
 }
 
 /********************************************************************

--- 1.116/tests/mysql_client_test.c	2005-05-12 11:16:08 +04:00
+++ 1.117/tests/mysql_client_test.c	2005-05-16 18:27:15 +04:00
@@ -13076,6 +13076,68 @@
 
 
 /*
+  Error message is returned for unsupported features.
+  Test also cursors with non-default PREFETCH_ROWS
+*/
+
+static void test_bug9643()
+{
+  MYSQL_STMT *stmt;
+  MYSQL_BIND bind[1];
+  int32 a;
+  int rc;
+  const char *stmt_text;
+  int num_rows= 0;
+  ulong type;
+  ulong prefetch_rows= 5;
+
+  myheader("test_bug9643");
+
+  mysql_query(mysql, "drop table if exists t1");
+  mysql_query(mysql, "create table t1 (id integer not null primary key)");
+  rc= mysql_query(mysql, "insert into t1 (id) values "
+                         " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
+  myquery(rc);
+
+  stmt= mysql_stmt_init(mysql);
+  /* Not implemented in 5.0 */
+  type= (ulong) CURSOR_TYPE_SCROLLABLE;
+  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
+  DIE_UNLESS(rc);
+  if (! opt_silent)
+    printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
+
+  type= (ulong) CURSOR_TYPE_READ_ONLY;
+  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
+  check_execute(stmt, rc);
+  rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
+                          (void*) &prefetch_rows);
+  check_execute(stmt, rc);
+  stmt_text= "select * from t1";
+  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+  check_execute(stmt, rc);
+
+  bzero(bind, sizeof(bind));
+  bind[0].buffer_type= MYSQL_TYPE_LONG;
+  bind[0].buffer= (void*) &a;
+  bind[0].buffer_length= sizeof(a);
+  mysql_stmt_bind_result(stmt, bind);
+
+  rc= mysql_stmt_execute(stmt);
+  check_execute(stmt, rc);
+
+  while ((rc= mysql_stmt_fetch(stmt)) == 0)
+    ++num_rows;
+  DIE_UNLESS(num_rows == 9);
+
+  rc= mysql_stmt_close(stmt);
+  DIE_UNLESS(rc == 0);
+
+  rc= mysql_query(mysql, "drop table t1");
+  myquery(rc);
+}
+
+/*
   Read and parse arguments and MySQL options from my.cnf
 */
 
@@ -13306,6 +13368,7 @@
   { "test_bug9159", test_bug9159 },
   { "test_bug9520", test_bug9520 },
   { "test_bug9478", test_bug9478 },
+  { "test_bug9643", test_bug9643 },
   { 0, 0 }
 };
 
Thread
bk commit into 5.0 tree (konstantin:1.1946) BUG#9643konstantin16 May