andrey          Wed Apr 27 13:53:19 2005 EDT

  Modified files:              
    /php-src/ext/mysqli mysqli_api.c 
  Log:
  fix bug #32013(MySQLi bind_result causes fatal error: memory limit reached)
  #this is a partial fix but it cannot be better. the user has to call
  #$stmt->store_result() and for a BLOB/MEDIUTEXT (and larger) space will be
  #allocated as big as the biggest column value.
  
  
http://cvs.php.net/diff.php/php-src/ext/mysqli/mysqli_api.c?r1=1.106&r2=1.107&ty=u
Index: php-src/ext/mysqli/mysqli_api.c
diff -u php-src/ext/mysqli/mysqli_api.c:1.106 
php-src/ext/mysqli/mysqli_api.c:1.107
--- php-src/ext/mysqli/mysqli_api.c:1.106       Wed Apr 20 09:24:08 2005
+++ php-src/ext/mysqli/mysqli_api.c     Wed Apr 27 13:53:15 2005
@@ -15,7 +15,7 @@
   | Author: Georg Richter <[EMAIL PROTECTED]>                                |
   +----------------------------------------------------------------------+
 
-  $Id: mysqli_api.c,v 1.106 2005/04/20 13:24:08 georg Exp $ 
+  $Id: mysqli_api.c,v 1.107 2005/04/27 17:53:15 andrey Exp $ 
 */
 
 #ifdef HAVE_CONFIG_H
@@ -313,9 +313,21 @@
 #ifdef FIELD_TYPE_NEWDECIMAL
                        case MYSQL_TYPE_NEWDECIMAL:
 #endif
-                               stmt->result.buf[ofs].type = IS_STRING; 
-                               stmt->result.buf[ofs].buflen =
-                                       (stmt->stmt->fields) ? 
(stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
+                               stmt->result.buf[ofs].type = IS_STRING;
+                               /*
+                                       If the user has called 
$stmt->store_result() then we have asked
+                                       max_length to be updated. this is done 
only for BLOBS because we don't want to allocate
+                                       big chunkgs of memory 2^16 or 2^24 
+                               */
+                               if (stmt->stmt->fields[ofs].max_length == 0) {
+                                       stmt->result.buf[ofs].buflen =
+                                               (stmt->stmt->fields) ? 
(stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
+                               } else {
+                                       /*
+                                               the user has called 
store_result(). if he does not there is no way to determine the
+                                       */
+                                       stmt->result.buf[ofs].buflen = 
stmt->stmt->fields[ofs].max_length;
+                               }
                                stmt->result.buf[ofs].val = (char 
*)emalloc(stmt->result.buf[ofs].buflen);
                                bind[ofs].buffer_type = MYSQL_TYPE_STRING;
                                bind[ofs].buffer = stmt->result.buf[ofs].val;
@@ -1858,12 +1870,28 @@
 {
        MY_STMT *stmt;
        zval    *mysql_stmt;
+       int             i=0;
 
        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
"O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
                return;
        }
        MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt"); 
        
+       /*
+         If the user wants to store the data and we have BLOBs/TEXTs we try to 
allocate
+         not the maximal length of the type (which is 16MB even for LONGBLOB) 
but
+         the maximal length of the field in the result set. If he/she has 
quite big
+         BLOB/TEXT columns after calling store_result() the memory usage of 
PHP will
+         double - but this is a known problem of the simple MySQL API ;)
+       */
+       for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
+               if (stmt->stmt->fields && stmt->stmt->fields[i].type == 
MYSQL_TYPE_BLOB) {
+                       my_bool tmp=1;
+                       mysql_stmt_attr_set(stmt->stmt, 
STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
+                       break;
+               }
+       }
+       
        if (mysql_stmt_store_result(stmt->stmt)){
                MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
                RETURN_FALSE;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to