Diff for /embedaddon/php/ext/pdo_odbc/odbc_stmt.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 23:47:59 version 1.1.1.4, 2013/10/14 08:02:28
Line 2 Line 2
   +----------------------------------------------------------------------+    +----------------------------------------------------------------------+
   | PHP Version 5                                                        |    | PHP Version 5                                                        |
   +----------------------------------------------------------------------+    +----------------------------------------------------------------------+
  | Copyright (c) 1997-2012 The PHP Group                                |  | Copyright (c) 1997-2013 The PHP Group                                |
   +----------------------------------------------------------------------+    +----------------------------------------------------------------------+
   | This source file is subject to version 3.0 of the PHP license,       |    | This source file is subject to version 3.0 of the PHP license,       |
   | that is bundled with this package in the file LICENSE, and is        |    | that is bundled with this package in the file LICENSE, and is        |
Line 286  static int odbc_stmt_param_hook(pdo_stmt_t *stmt, stru Line 286  static int odbc_stmt_param_hook(pdo_stmt_t *stmt, stru
         if (param->is_param) {          if (param->is_param) {
   
                 switch (event_type) {                  switch (event_type) {
                           case PDO_PARAM_EVT_FETCH_PRE:
                           case PDO_PARAM_EVT_FETCH_POST:
                           case PDO_PARAM_EVT_NORMALIZE:
                                   /* Do nothing */
                                   break;
   
                         case PDO_PARAM_EVT_FREE:                          case PDO_PARAM_EVT_FREE:
                                 P = param->driver_data;                                  P = param->driver_data;
                                 if (P) {                                  if (P) {
Line 543  static int odbc_stmt_describe(pdo_stmt_t *stmt, int co Line 549  static int odbc_stmt_describe(pdo_stmt_t *stmt, int co
 {  {
         pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;          pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
         struct pdo_column_data *col = &stmt->columns[colno];          struct pdo_column_data *col = &stmt->columns[colno];
         zend_bool dyn = FALSE;  
         RETCODE rc;          RETCODE rc;
         SWORD   colnamelen;          SWORD   colnamelen;
         SDWORD  colsize, displaysize;          SDWORD  colsize, displaysize;
Line 614  static int odbc_stmt_get_col(pdo_stmt_t *stmt, int col Line 619  static int odbc_stmt_get_col(pdo_stmt_t *stmt, int col
   
         /* if it is a column containing "long" data, perform late binding now */          /* if it is a column containing "long" data, perform late binding now */
         if (C->is_long) {          if (C->is_long) {
                 unsigned long alloced = 4096;  
                 unsigned long used = 0;                  unsigned long used = 0;
                 char *buf;                  char *buf;
                 RETCODE rc;                  RETCODE rc;
Line 633  static int odbc_stmt_get_col(pdo_stmt_t *stmt, int col Line 637  static int odbc_stmt_get_col(pdo_stmt_t *stmt, int col
                 }                  }
   
                 if (rc == SQL_SUCCESS_WITH_INFO) {                  if (rc == SQL_SUCCESS_WITH_INFO) {
                        /* promote up to a bigger buffer */                        /* this is a 'long column'
 
                        if (C->fetched_len != SQL_NO_TOTAL) { 
                                /* use size suggested by the driver, if it knows it */ 
                                alloced = C->fetched_len + 1; 
                        } 
                                                   
                        buf = emalloc(alloced);                         read the column in 255 byte blocks until the end of the column is reached, reassembling those blocks
                        memcpy(buf, C->data, 256);                         in order into the output buffer
                        used = 255; /* not 256; the driver NUL terminated the buffer */                        
                          this loop has to work whether or not SQLGetData() provides the total column length.
                          calling SQLDescribeCol() or other, specifically to get the column length, then doing a single read
                          for that size would be slower except maybe for extremely long columns.*/
                         char *buf2;
   
                           buf2 = emalloc(256);
                           buf = estrndup(C->data, 256);
                           used = 255; /* not 256; the driver NUL terminated the buffer */
                           
                         do {                          do {
                                 C->fetched_len = 0;                                  C->fetched_len = 0;
                                rc = SQLGetData(S->stmt, colno+1, SQL_C_CHAR,                                /* read block. 256 bytes => 255 bytes are actually read, the last 1 is NULL */
                                        buf + used, alloced - used,                                rc = SQLGetData(S->stmt, colno+1, SQL_C_CHAR, buf2, 256, &C->fetched_len);
                                        &C->fetched_len);                                
                                /* resize output buffer and reassemble block */
                                if (rc == SQL_NO_DATA) {                                if (rc==SQL_SUCCESS_WITH_INFO) {
                                        /* we got the lot */                                        /* point 5, in section "Retrieving Data with SQLGetData" in http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441(v=vs.85).aspx
                                        break;                                         states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > 255 (greater than buf2's size)
                                } else if (rc != SQL_SUCCESS) {                                         (if a driver fails to follow that and wrote less than 255 bytes to buf2, this will AV or read garbage into buf) */
                                        pdo_odbc_stmt_error("SQLGetData");                                        buf = erealloc(buf, used + 255+1);
                                        if (rc != SQL_SUCCESS_WITH_INFO) {                                        memcpy(buf + used, buf2, 255);
                                                break;                                        used = used + 255;
                                        }                                } else if (rc==SQL_SUCCESS) {
                                }                                        buf = erealloc(buf, used + C->fetched_len+1);
                                        memcpy(buf + used, buf2, C->fetched_len);
                                if (C->fetched_len == SQL_NO_TOTAL) {                                        used = used + C->fetched_len;
                                        used += alloced - used; 
                                 } else {                                  } else {
                                        used += C->fetched_len;                                        /* includes SQL_NO_DATA */
                                } 
 
                                if (rc == SQL_SUCCESS) { 
                                        /* this was the final fetch */ 
                                         break;                                          break;
                                 }                                  }
                                
                                /* we need to fetch another chunk; resize the 
                                 * buffer */ 
                                alloced *= 2; 
                                buf = erealloc(buf, alloced); 
                         } while (1);                          } while (1);
                        
                        /* size down */                        efree(buf2);
                        if (used < alloced - 1024) {                        
                                alloced = used+1;                        /* NULL terminate the buffer once, when finished, for use with the rest of PHP */
                                buf = erealloc(buf, used+1); 
                        } 
                         buf[used] = '\0';                          buf[used] = '\0';
   
                         *ptr = buf;                          *ptr = buf;
                         *caller_frees = 1;                          *caller_frees = 1;
                         *len = used;                          *len = used;

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>