PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/mysqlnd - mysqlnd_ps_codec.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 448 0.0 %
Date: 2014-04-16 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 2006-2014 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Andrey Hristov <andrey@mysql.com>                           |
      16             :   |          Ulf Wendel <uwendel@mysql.com>                              |
      17             :   |          Georg Richter <georg@mysql.com>                             |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : #include "php.h"
      23             : #include "mysqlnd.h"
      24             : #include "mysqlnd_wireprotocol.h"
      25             : #include "mysqlnd_priv.h"
      26             : #include "mysqlnd_debug.h"
      27             : 
      28             : #define MYSQLND_SILENT
      29             : 
      30             : 
      31             : enum mysqlnd_timestamp_type
      32             : {
      33             :   MYSQLND_TIMESTAMP_NONE= -2,
      34             :   MYSQLND_TIMESTAMP_ERROR= -1,
      35             :   MYSQLND_TIMESTAMP_DATE= 0,
      36             :   MYSQLND_TIMESTAMP_DATETIME= 1,
      37             :   MYSQLND_TIMESTAMP_TIME= 2
      38             : };
      39             : 
      40             : 
      41             : struct st_mysqlnd_time
      42             : {
      43             :   unsigned int  year, month, day, hour, minute, second;
      44             :   unsigned long second_part;
      45             :   zend_bool     neg;
      46             :   enum mysqlnd_timestamp_type time_type;
      47             : };
      48             : 
      49             : 
      50             : struct st_mysqlnd_perm_bind mysqlnd_ps_fetch_functions[MYSQL_TYPE_LAST + 1];
      51             : 
      52             : #define MYSQLND_PS_SKIP_RESULT_W_LEN    -1
      53             : #define MYSQLND_PS_SKIP_RESULT_STR              -2
      54             : 
      55             : /* {{{ ps_fetch_from_1_to_8_bytes */
      56             : void
      57           0 : ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len,
      58             :                                                    zend_uchar ** row, unsigned int byte_count TSRMLS_DC)
      59             : {
      60             :         char tmp[22];
      61           0 :         size_t tmp_len = 0;
      62           0 :         zend_bool is_bit = field->type == MYSQL_TYPE_BIT;
      63           0 :         DBG_ENTER("ps_fetch_from_1_to_8_bytes");
      64           0 :         DBG_INF_FMT("zv=%p byte_count=%u", zv, byte_count);
      65           0 :         if (field->flags & UNSIGNED_FLAG) {
      66           0 :                 uint64_t uval = 0;
      67             : 
      68           0 :                 switch (byte_count) {
      69           0 :                         case 8:uval = is_bit? (uint64_t) bit_uint8korr(*row):(uint64_t) uint8korr(*row);break;
      70           0 :                         case 7:uval = bit_uint7korr(*row);break;
      71           0 :                         case 6:uval = bit_uint6korr(*row);break;
      72           0 :                         case 5:uval = bit_uint5korr(*row);break;
      73           0 :                         case 4:uval = is_bit? (uint64_t) bit_uint4korr(*row):(uint64_t) uint4korr(*row);break;
      74           0 :                         case 3:uval = is_bit? (uint64_t) bit_uint3korr(*row):(uint64_t) uint3korr(*row);break;
      75           0 :                         case 2:uval = is_bit? (uint64_t) bit_uint2korr(*row):(uint64_t) uint2korr(*row);break;
      76           0 :                         case 1:uval = (uint64_t) uint1korr(*row);break;
      77             :                 }
      78             : 
      79             : #if SIZEOF_LONG==4
      80             :                 if (uval > INT_MAX) {
      81             :                         DBG_INF("stringify");
      82             :                         tmp_len = sprintf((char *)&tmp, MYSQLND_LLU_SPEC, uval);
      83             :                 } else 
      84             : #endif /* #if SIZEOF_LONG==4 */
      85             :                 {
      86           0 :                         if (byte_count < 8 || uval <= L64(9223372036854775807)) {
      87           0 :                                 ZVAL_LONG(zv, (long) uval); /* the cast is safe, we are in the range */
      88             :                         } else {
      89           0 :                                 DBG_INF("stringify");
      90           0 :                                 tmp_len = sprintf((char *)&tmp, MYSQLND_LLU_SPEC, uval);
      91             :                         }
      92             :                 }
      93             :         } else {
      94             :                 /* SIGNED */
      95           0 :                 int64_t lval = 0;
      96           0 :                 switch (byte_count) {
      97           0 :                         case 8:lval = (int64_t) sint8korr(*row);break;
      98             :                         /*
      99             :                           7, 6 and 5 are not possible.
     100             :                           BIT is only unsigned, thus only uint5|6|7 macroses exist
     101             :                         */
     102           0 :                         case 4:lval = (int64_t) sint4korr(*row);break;
     103           0 :                         case 3:lval = (int64_t) sint3korr(*row);break;
     104           0 :                         case 2:lval = (int64_t) sint2korr(*row);break;
     105           0 :                         case 1:lval = (int64_t) *(int8_t*)*row;break;
     106             :                 }
     107             : 
     108             : #if SIZEOF_LONG==4
     109             :                 if ((L64(2147483647) < (int64_t) lval) || (L64(-2147483648) > (int64_t) lval)) {
     110             :                         DBG_INF("stringify");
     111             :                         tmp_len = sprintf((char *)&tmp, MYSQLND_LL_SPEC, lval);
     112             :                 } else
     113             : #endif /* SIZEOF */
     114             :                 {
     115           0 :                         ZVAL_LONG(zv, (long) lval); /* the cast is safe, we are in the range */
     116             :                 }
     117             :         }
     118             : 
     119           0 :         if (tmp_len) {
     120           0 :                 ZVAL_STRINGL(zv, tmp, tmp_len, 1);
     121             :         }
     122           0 :         (*row)+= byte_count;
     123           0 :         DBG_VOID_RETURN;
     124             : }
     125             : /* }}} */
     126             : 
     127             : 
     128             : /* {{{ ps_fetch_null */
     129             : static void
     130           0 : ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     131             : {
     132           0 :         ZVAL_NULL(zv);
     133           0 : }
     134             : /* }}} */
     135             : 
     136             : 
     137             : /* {{{ ps_fetch_int8 */
     138             : static void
     139           0 : ps_fetch_int8(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     140             : {
     141           0 :         ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 1 TSRMLS_CC);
     142           0 : }
     143             : /* }}} */
     144             : 
     145             : 
     146             : /* {{{ ps_fetch_int16 */
     147             : static void
     148           0 : ps_fetch_int16(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     149             : {
     150           0 :         ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 2 TSRMLS_CC);
     151           0 : }
     152             : /* }}} */
     153             : 
     154             : 
     155             : /* {{{ ps_fetch_int32 */
     156             : static void
     157           0 : ps_fetch_int32(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     158             : {
     159           0 :         ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 4 TSRMLS_CC);
     160           0 : }
     161             : /* }}} */
     162             : 
     163             : 
     164             : /* {{{ ps_fetch_int64 */
     165             : static void
     166           0 : ps_fetch_int64(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     167             : {
     168           0 :         ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 8 TSRMLS_CC);
     169           0 : }
     170             : /* }}} */
     171             : 
     172             : 
     173             : /* {{{ ps_fetch_float */
     174             : static void
     175           0 : ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     176             : {
     177             :         float value;
     178           0 :         DBG_ENTER("ps_fetch_float");
     179           0 :         float4get(value, *row);
     180           0 :         ZVAL_DOUBLE(zv, value);
     181           0 :         (*row)+= 4;
     182           0 :         DBG_INF_FMT("value=%f", value);
     183           0 :         DBG_VOID_RETURN;
     184             : }
     185             : /* }}} */
     186             : 
     187             : 
     188             : /* {{{ ps_fetch_double */
     189             : static void
     190           0 : ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     191             : {
     192             :         double value;
     193           0 :         DBG_ENTER("ps_fetch_double");
     194           0 :         float8get(value, *row);
     195           0 :         ZVAL_DOUBLE(zv, value);
     196           0 :         (*row)+= 8;
     197           0 :         DBG_INF_FMT("value=%f", value);
     198           0 :         DBG_VOID_RETURN;
     199             : }
     200             : /* }}} */
     201             : 
     202             : 
     203             : /* {{{ ps_fetch_time */
     204             : static void
     205           0 : ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     206             : {
     207             :         struct st_mysqlnd_time t;
     208             :         unsigned long length; /* First byte encodes the length*/
     209             :         char * value;
     210           0 :         DBG_ENTER("ps_fetch_time");
     211             : 
     212           0 :         if ((length = php_mysqlnd_net_field_length(row))) {
     213           0 :                 zend_uchar * to= *row;
     214             : 
     215           0 :                 t.time_type = MYSQLND_TIMESTAMP_TIME;
     216           0 :                 t.neg                   = (zend_bool) to[0];
     217             : 
     218           0 :                 t.day                   = (unsigned long) sint4korr(to+1);
     219           0 :                 t.hour                  = (unsigned int) to[5];
     220           0 :                 t.minute                = (unsigned int) to[6];
     221           0 :                 t.second                = (unsigned int) to[7];
     222           0 :                 t.second_part   = (length > 8) ? (unsigned long) sint4korr(to+8) : 0;
     223           0 :                 t.year                  = t.month= 0;
     224           0 :                 if (t.day) {
     225             :                         /* Convert days to hours at once */
     226           0 :                         t.hour += t.day*24;
     227           0 :                         t.day   = 0;
     228             :                 }
     229             : 
     230           0 :                 (*row) += length;
     231             :         } else {
     232           0 :                 memset(&t, 0, sizeof(t));
     233           0 :                 t.time_type = MYSQLND_TIMESTAMP_TIME;
     234             :         }
     235             : 
     236           0 :         length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second);
     237             : 
     238           0 :         DBG_INF_FMT("%s", value);
     239           0 :         ZVAL_STRINGL(zv, value, length, 1);
     240           0 :         mnd_sprintf_free(value);
     241           0 :         DBG_VOID_RETURN;
     242             : }
     243             : /* }}} */
     244             : 
     245             : 
     246             : /* {{{ ps_fetch_date */
     247             : static void
     248           0 : ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     249             : {
     250           0 :         struct st_mysqlnd_time t = {0};
     251             :         unsigned long length; /* First byte encodes the length*/
     252             :         char * value;
     253           0 :         DBG_ENTER("ps_fetch_date");
     254             : 
     255           0 :         if ((length = php_mysqlnd_net_field_length(row))) {
     256           0 :                 zend_uchar *to= *row;
     257             : 
     258           0 :                 t.time_type= MYSQLND_TIMESTAMP_DATE;
     259           0 :                 t.neg= 0;
     260             : 
     261           0 :                 t.second_part = t.hour = t.minute = t.second = 0;
     262             : 
     263           0 :                 t.year  = (unsigned int) sint2korr(to);
     264           0 :                 t.month = (unsigned int) to[2];
     265           0 :                 t.day   = (unsigned int) to[3];
     266             : 
     267           0 :                 (*row)+= length;
     268             :         } else {
     269           0 :                 memset(&t, 0, sizeof(t));
     270           0 :                 t.time_type = MYSQLND_TIMESTAMP_DATE;
     271             :         }
     272             : 
     273           0 :         length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day);
     274             : 
     275           0 :         DBG_INF_FMT("%s", value);
     276           0 :         ZVAL_STRINGL(zv, value, length, 1);
     277           0 :         mnd_sprintf_free(value);
     278           0 :         DBG_VOID_RETURN;
     279             : }
     280             : /* }}} */
     281             : 
     282             : 
     283             : /* {{{ ps_fetch_datetime */
     284             : static void
     285           0 : ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     286             : {
     287             :         struct st_mysqlnd_time t;
     288             :         unsigned long length; /* First byte encodes the length*/
     289             :         char * value;
     290           0 :         DBG_ENTER("ps_fetch_datetime");
     291             : 
     292           0 :         if ((length = php_mysqlnd_net_field_length(row))) {
     293           0 :                 zend_uchar * to = *row;
     294             : 
     295           0 :                 t.time_type = MYSQLND_TIMESTAMP_DATETIME;
     296           0 :                 t.neg    = 0;
     297             : 
     298           0 :                 t.year   = (unsigned int) sint2korr(to);
     299           0 :                 t.month = (unsigned int) to[2];
     300           0 :                 t.day    = (unsigned int) to[3];
     301             : 
     302           0 :                 if (length > 4) {
     303           0 :                         t.hour   = (unsigned int) to[4];
     304           0 :                         t.minute = (unsigned int) to[5];
     305           0 :                         t.second = (unsigned int) to[6];
     306             :                 } else {
     307           0 :                         t.hour = t.minute = t.second= 0;
     308             :                 }
     309           0 :                 t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0;
     310             : 
     311           0 :                 (*row)+= length;
     312             :         } else {
     313           0 :                 memset(&t, 0, sizeof(t));
     314           0 :                 t.time_type = MYSQLND_TIMESTAMP_DATETIME;
     315             :         }
     316             : 
     317           0 :         length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second);
     318             : 
     319           0 :         DBG_INF_FMT("%s", value);
     320           0 :         ZVAL_STRINGL(zv, value, length, 1);
     321           0 :         mnd_sprintf_free(value);
     322           0 :         DBG_VOID_RETURN;
     323             : }
     324             : /* }}} */
     325             : 
     326             : 
     327             : /* {{{ ps_fetch_string */
     328             : static void
     329           0 : ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     330             : {
     331             :         /*
     332             :           For now just copy, before we make it possible
     333             :           to write \0 to the row buffer
     334             :         */
     335           0 :         const unsigned long length = php_mysqlnd_net_field_length(row);
     336           0 :         DBG_ENTER("ps_fetch_string");
     337           0 :         DBG_INF_FMT("len = %lu", length);
     338           0 :         DBG_INF("copying from the row buffer");
     339           0 :         ZVAL_STRINGL(zv, (char *)*row, length, 1);
     340             : 
     341           0 :         (*row) += length;
     342           0 :         DBG_VOID_RETURN;
     343             : }
     344             : /* }}} */
     345             : 
     346             : 
     347             : /* {{{ ps_fetch_bit */
     348             : static void
     349           0 : ps_fetch_bit(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
     350             : {
     351           0 :         unsigned long length = php_mysqlnd_net_field_length(row);
     352           0 :         ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, length TSRMLS_CC);
     353           0 : }
     354             : /* }}} */
     355             : 
     356             : 
     357             : /* {{{ _mysqlnd_init_ps_fetch_subsystem */
     358           0 : void _mysqlnd_init_ps_fetch_subsystem()
     359             : {
     360           0 :         memset(mysqlnd_ps_fetch_functions, 0, sizeof(mysqlnd_ps_fetch_functions));
     361           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].func                = ps_fetch_null;
     362           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].pack_len    = 0;
     363           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].php_type    = IS_NULL;
     364           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].can_ret_as_str_in_uni       = TRUE;
     365             : 
     366           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].func                = ps_fetch_int8;
     367           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].pack_len    = 1;
     368           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].php_type    = IS_LONG;
     369           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].can_ret_as_str_in_uni       = TRUE;
     370             : 
     371           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].func               = ps_fetch_int16;
     372           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].pack_len   = 2;
     373           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].php_type   = IS_LONG;
     374           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].can_ret_as_str_in_uni      = TRUE;
     375             : 
     376           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].func                = ps_fetch_int16;
     377           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].pack_len    = 2;
     378           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].php_type    = IS_LONG;
     379           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].can_ret_as_str_in_uni       = TRUE;
     380             : 
     381           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].func               = ps_fetch_int32;
     382           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].pack_len   = 4;
     383           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].php_type   = IS_LONG;
     384           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].can_ret_as_str_in_uni      = TRUE;
     385             : 
     386           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].func                = ps_fetch_int32;
     387           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].pack_len    = 4;
     388           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].php_type    = IS_LONG;
     389           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].can_ret_as_str_in_uni       = TRUE;
     390             : 
     391           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].func    = ps_fetch_int64;
     392           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].pack_len= 8;
     393           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].php_type= IS_LONG;
     394           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].can_ret_as_str_in_uni   = TRUE;
     395             : 
     396           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].func               = ps_fetch_float;
     397           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].pack_len   = 4;
     398           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].php_type   = IS_DOUBLE;
     399           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].can_ret_as_str_in_uni      = TRUE;
     400             : 
     401           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].func              = ps_fetch_double;
     402           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].pack_len  = 8;
     403           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].php_type  = IS_DOUBLE;
     404           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].can_ret_as_str_in_uni     = TRUE;
     405             : 
     406           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].func                = ps_fetch_time;
     407           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].pack_len    = MYSQLND_PS_SKIP_RESULT_W_LEN;
     408           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].php_type    = IS_STRING;
     409           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].can_ret_as_str_in_uni       = TRUE;
     410             : 
     411           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].func                = ps_fetch_date;
     412           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].pack_len    = MYSQLND_PS_SKIP_RESULT_W_LEN;
     413           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].php_type    = IS_STRING;
     414           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].can_ret_as_str_in_uni       = TRUE;
     415             : 
     416           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].func             = ps_fetch_string;
     417           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN;
     418           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].php_type = IS_STRING;
     419           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].can_ret_as_str_in_uni    = TRUE;
     420             : 
     421           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].func    = ps_fetch_datetime;
     422           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN;
     423           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].php_type= IS_STRING;
     424           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].can_ret_as_str_in_uni   = TRUE;
     425             : 
     426           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].func   = ps_fetch_datetime;
     427           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN;
     428           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING;
     429           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].can_ret_as_str_in_uni  = TRUE;
     430             : 
     431           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func   = ps_fetch_string;
     432           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
     433           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].php_type = IS_STRING;
     434           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].is_possibly_blob = TRUE;
     435           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].can_ret_as_str_in_uni  = TRUE;
     436             : 
     437           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].func                = ps_fetch_string;
     438           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].pack_len    = MYSQLND_PS_SKIP_RESULT_STR;
     439           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].php_type    = IS_STRING;
     440           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].is_possibly_blob = TRUE;
     441           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].can_ret_as_str_in_uni       = TRUE;
     442             : 
     443           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].func         = ps_fetch_string;
     444           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].pack_len     = MYSQLND_PS_SKIP_RESULT_STR;
     445           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].php_type     = IS_STRING;
     446           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].is_possibly_blob = TRUE;
     447           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].can_ret_as_str_in_uni        = TRUE;
     448             : 
     449           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].func           = ps_fetch_string;
     450           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].pack_len       = MYSQLND_PS_SKIP_RESULT_STR;
     451           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].php_type       = IS_STRING;
     452           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].is_possibly_blob = TRUE;
     453           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].can_ret_as_str_in_uni  = TRUE;
     454             : 
     455           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].func         = ps_fetch_bit;
     456           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].pack_len     = 8;
     457           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].php_type     = IS_LONG;
     458           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].can_ret_as_str_in_uni = TRUE;
     459             : 
     460           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].func          = ps_fetch_string;
     461           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].pack_len      = MYSQLND_PS_SKIP_RESULT_STR;
     462           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].php_type = IS_STRING;
     463           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].is_possibly_blob = TRUE;
     464             : 
     465           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].func             = ps_fetch_string;
     466           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].pack_len = MYSQLND_PS_SKIP_RESULT_STR;
     467           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].php_type = IS_STRING;
     468           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].is_possibly_blob = TRUE;
     469             : 
     470           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].func                      = ps_fetch_string;
     471           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].pack_len          = MYSQLND_PS_SKIP_RESULT_STR;
     472           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].php_type  = IS_STRING;
     473           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].is_possibly_blob = TRUE;
     474             : 
     475           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].func             = ps_fetch_string;
     476           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].pack_len = MYSQLND_PS_SKIP_RESULT_STR;
     477           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].php_type = IS_STRING;
     478           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].can_ret_as_str_in_uni    = TRUE;
     479             : 
     480           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].func          = ps_fetch_string;
     481           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].pack_len      = MYSQLND_PS_SKIP_RESULT_STR;
     482           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].php_type      = IS_STRING;
     483           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].can_ret_as_str_in_uni = TRUE;
     484             : 
     485           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].func                = ps_fetch_string;
     486           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].pack_len    = MYSQLND_PS_SKIP_RESULT_STR;
     487           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].php_type    = IS_STRING;
     488             : 
     489           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SET].func                 = ps_fetch_string;
     490           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SET].pack_len             = MYSQLND_PS_SKIP_RESULT_STR;
     491           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_SET].php_type             = IS_STRING;
     492             : 
     493           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_GEOMETRY].func    = ps_fetch_string;
     494           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_GEOMETRY].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
     495           0 :         mysqlnd_ps_fetch_functions[MYSQL_TYPE_GEOMETRY].php_type= IS_STRING;
     496           0 : }
     497             : /* }}} */
     498             : 
     499             : 
     500             : /* {{{ mysqlnd_stmt_copy_it */
     501             : static enum_func_status
     502           0 : mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count, unsigned int current TSRMLS_DC)
     503             : {
     504           0 :         if (!*copies) {
     505           0 :                 *copies = mnd_ecalloc(param_count, sizeof(zval *));
     506             :         }
     507           0 :         if (*copies) {
     508           0 :                 MAKE_STD_ZVAL((*copies)[current]);
     509           0 :                 *(*copies)[current] = *original;
     510           0 :                 Z_SET_REFCOUNT_P((*copies)[current], 1);
     511           0 :                 zval_copy_ctor((*copies)[current]);
     512           0 :                 return PASS;
     513             :         }
     514           0 :         return FAIL;
     515             : }
     516             : /* }}} */
     517             : 
     518             : 
     519             : /* {{{ mysqlnd_stmt_free_copies */
     520             : static void
     521           0 : mysqlnd_stmt_free_copies(MYSQLND_STMT_DATA * stmt, zval ** copies TSRMLS_DC)
     522             : {
     523           0 :         if (copies) {
     524             :                 unsigned int i;
     525           0 :                 for (i = 0; i < stmt->param_count; i++) {
     526           0 :                         if (copies[i]) {
     527           0 :                                 zval_ptr_dtor(&copies[i]);
     528             :                         }
     529             :                 }
     530           0 :                 mnd_efree(copies);
     531             :         }
     532           0 : }
     533             : /* }}} */
     534             : 
     535             : 
     536             : /* {{{ mysqlnd_stmt_execute_check_n_enlarge_buffer */
     537             : static enum_func_status
     538           0 : mysqlnd_stmt_execute_check_n_enlarge_buffer(zend_uchar **buf, zend_uchar **p, size_t * buf_len, zend_uchar * const provided_buffer, size_t needed_bytes TSRMLS_DC)
     539             : {
     540           0 :         const size_t overalloc = 5;
     541           0 :         size_t left = (*buf_len - (*p - *buf));
     542             : 
     543           0 :         if (left < (needed_bytes + overalloc)) {
     544           0 :                 size_t offset = *p - *buf;
     545             :                 zend_uchar *tmp_buf;
     546           0 :                 *buf_len = offset + needed_bytes + overalloc;
     547           0 :                 tmp_buf = mnd_emalloc(*buf_len);
     548           0 :                 if (!tmp_buf) {
     549           0 :                         return FAIL;
     550             :                 }
     551           0 :                 memcpy(tmp_buf, *buf, offset);
     552           0 :                 if (*buf != provided_buffer) {
     553           0 :                         mnd_efree(*buf);
     554             :                 }
     555           0 :                 *buf = tmp_buf;
     556             :                 /* Update our pos pointer */
     557           0 :                 *p = *buf + offset;
     558             :         }
     559           0 :         return PASS;
     560             : }
     561             : /* }}} */
     562             : 
     563             : 
     564             : /* {{{ mysqlnd_stmt_execute_prepare_param_types */
     565             : static enum_func_status
     566           0 : mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval *** copies_param, int * resend_types_next_time TSRMLS_DC)
     567             : {
     568             :         unsigned int i;
     569           0 :         DBG_ENTER("mysqlnd_stmt_execute_prepare_param_types");
     570           0 :         for (i = 0; i < stmt->param_count; i++) {
     571           0 :                 short current_type = stmt->param_bind[i].type;
     572             : 
     573           0 :                 if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
     574             :                         zval ** copies;
     575             :                         /* always copy the var, because we do many conversions */
     576           0 :                         if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG &&
     577           0 :                                 PASS != mysqlnd_stmt_copy_it(copies_param, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
     578             :                         {
     579           0 :                                 SET_OOM_ERROR(*stmt->error_info);
     580           0 :                                 goto end;
     581             :                         }
     582           0 :                         copies = *copies_param;
     583             :                         /*
     584             :                           if it doesn't fit in a long send it as a string.
     585             :                           Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
     586             :                         */
     587           0 :                         if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
     588           0 :                                 zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
     589             :                                 /*
     590             :                                   Because converting to double and back to long can lead
     591             :                                   to losing precision we need second variable. Conversion to double is to see if 
     592             :                                   value is too big for a long. As said, precision could be lost.
     593             :                                 */
     594             :                                 zval *tmp_data_copy;
     595           0 :                                 MAKE_STD_ZVAL(tmp_data_copy);
     596           0 :                                 *tmp_data_copy = *tmp_data;
     597           0 :                                 Z_SET_REFCOUNT_P(tmp_data_copy, 1);
     598           0 :                                 zval_copy_ctor(tmp_data_copy);
     599           0 :                                 convert_to_double_ex(&tmp_data_copy);
     600             : 
     601             :                                 /*
     602             :                                   if it doesn't fit in a long send it as a string.
     603             :                                   Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
     604             :                                   We do transformation here, which will be used later when sending types. The code later relies on this.
     605             :                                 */
     606           0 :                                 if (Z_DVAL_P(tmp_data_copy) > LONG_MAX || Z_DVAL_P(tmp_data_copy) < LONG_MIN) {
     607           0 :                                         stmt->send_types_to_server = *resend_types_next_time = 1;
     608           0 :                                         convert_to_string_ex(&tmp_data);
     609             :                                 } else {
     610           0 :                                         convert_to_long_ex(&tmp_data);
     611             :                                 }
     612             : 
     613           0 :                                 zval_ptr_dtor(&tmp_data_copy);
     614             :                         }
     615             :                 }
     616             :         }
     617           0 :         DBG_RETURN(PASS);
     618             : end:
     619           0 :         DBG_RETURN(FAIL);
     620             : }
     621             : /* }}} */
     622             : 
     623             : 
     624             : /* {{{ mysqlnd_stmt_execute_store_types */
     625             : static void
     626           0 : mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_uchar ** p)
     627             : {
     628             :         unsigned int i;
     629           0 :         for (i = 0; i < stmt->param_count; i++) {
     630           0 :                 short current_type = stmt->param_bind[i].type;
     631             :                 /* our types are not unsigned */
     632             : #if SIZEOF_LONG==8  
     633           0 :                 if (current_type == MYSQL_TYPE_LONG) {
     634           0 :                         current_type = MYSQL_TYPE_LONGLONG;
     635             :                 }
     636             : #endif
     637           0 :                 if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
     638             :                         /*
     639             :                           if it doesn't fit in a long send it as a string.
     640             :                           Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
     641             :                         */
     642           0 :                         if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
     643           0 :                                 const zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
     644             :                                 /*
     645             :                                   In case of IS_LONG we do nothing, it is ok, in case of string, we just need to set current_type.
     646             :                                   The actual transformation has been performed several dozens line above.
     647             :                                 */
     648           0 :                                 if (Z_TYPE_P(tmp_data) == IS_STRING) {
     649           0 :                                         current_type = MYSQL_TYPE_VAR_STRING;
     650             :                                         /*
     651             :                                           don't change stmt->param_bind[i].type to MYSQL_TYPE_VAR_STRING
     652             :                                           we force convert_to_long_ex in all cases, thus the type will be right in the next switch.
     653             :                                           if the type is however not long, then we will do a goto in the next switch.
     654             :                                           We want to preserve the original bind type given by the user. Thus, we do these hacks.
     655             :                                         */
     656             :                                 }
     657             :                         }
     658             :                 }
     659           0 :                 int2store(*p, current_type);
     660           0 :                 *p+= 2;
     661             :         }
     662           0 : }
     663             : /* }}} */
     664             : 
     665             : 
     666             : /* {{{ mysqlnd_stmt_execute_calculate_param_values_size */
     667             : static enum_func_status
     668           0 : mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval *** copies_param, size_t * data_size TSRMLS_DC)
     669             : {
     670             :         unsigned int i;
     671           0 :         DBG_ENTER("mysqlnd_stmt_execute_calculate_param_values_size");
     672           0 :         for (i = 0; i < stmt->param_count; i++) {
     673           0 :                 unsigned short is_longlong = 0;
     674             :                 unsigned int j;
     675           0 :                 zval *the_var = stmt->param_bind[i].zv;
     676             : 
     677           0 :                 if (!the_var || (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
     678           0 :                         continue;
     679             :                 }
     680           0 :                 for (j = i + 1; j < stmt->param_count; j++) {
     681           0 :                         if (stmt->param_bind[j].zv == the_var) {
     682             :                                 /* Double binding of the same zval, make a copy */
     683           0 :                                 if (!*copies_param || !(*copies_param)[i]) {
     684           0 :                                         if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
     685           0 :                                                 SET_OOM_ERROR(*stmt->error_info);
     686           0 :                                                 goto end;
     687             :                                         }
     688             :                                 }
     689           0 :                                 break;
     690             :                         }
     691             :                 }
     692             : 
     693           0 :                 switch (stmt->param_bind[i].type) {
     694             :                         case MYSQL_TYPE_DOUBLE:
     695           0 :                                 *data_size += 8;
     696           0 :                                 if (Z_TYPE_P(the_var) != IS_DOUBLE) {
     697           0 :                                         if (!*copies_param || !(*copies_param)[i]) {
     698           0 :                                                 if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
     699           0 :                                                         SET_OOM_ERROR(*stmt->error_info);
     700           0 :                                                         goto end;
     701             :                                                 }
     702             :                                         }
     703             :                                 }
     704           0 :                                 break;
     705             :                         case MYSQL_TYPE_LONGLONG:
     706           0 :                                 is_longlong = 4;
     707             :                                 /* fall-through */
     708             :                         case MYSQL_TYPE_LONG:
     709             :                                 {
     710           0 :                                         zval *tmp_data = (*copies_param && (*copies_param)[i])? (*copies_param)[i]: stmt->param_bind[i].zv;
     711           0 :                                         if (Z_TYPE_P(tmp_data) == IS_STRING) {
     712           0 :                                                 goto use_string;
     713             :                                         }
     714           0 :                                         convert_to_long_ex(&tmp_data);
     715             :                                 }
     716           0 :                                 *data_size += 4 + is_longlong;
     717           0 :                                 break;
     718             :                         case MYSQL_TYPE_LONG_BLOB:
     719           0 :                                 if (!(stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED)) {
     720             :                                         /*
     721             :                                           User hasn't sent anything, we will send empty string.
     722             :                                           Empty string has length of 0, encoded in 1 byte. No real
     723             :                                           data will follows after it.
     724             :                                         */
     725           0 :                                         (*data_size)++;
     726             :                                 }
     727           0 :                                 break;
     728             :                         case MYSQL_TYPE_VAR_STRING:
     729             : use_string:
     730           0 :                                 *data_size += 8; /* max 8 bytes for size */
     731           0 :                                 if (Z_TYPE_P(the_var) != IS_STRING) {
     732           0 :                                         if (!*copies_param || !(*copies_param)[i]) {
     733           0 :                                                 if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
     734           0 :                                                         SET_OOM_ERROR(*stmt->error_info);
     735           0 :                                                         goto end;
     736             :                                                 }
     737             :                                         }
     738           0 :                                         the_var = (*copies_param)[i];
     739             :                                 }
     740           0 :                                 convert_to_string_ex(&the_var);
     741           0 :                                 *data_size += Z_STRLEN_P(the_var);
     742             :                                 break;
     743             :                 }
     744             :         }
     745           0 :         DBG_RETURN(PASS);
     746             : end:
     747           0 :         DBG_RETURN(FAIL);
     748             : }
     749             : /* }}} */
     750             : 
     751             : 
     752             : /* {{{ mysqlnd_stmt_execute_store_param_values */
     753             : static void
     754           0 : mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_uchar * buf, zend_uchar ** p, size_t null_byte_offset)
     755             : {
     756             :         unsigned int i;
     757           0 :         for (i = 0; i < stmt->param_count; i++) {
     758           0 :                 zval * data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
     759             :                 /* Handle long data */
     760           0 :                 if (stmt->param_bind[i].zv && Z_TYPE_P(data) == IS_NULL) {
     761           0 :                         (buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
     762             :                 } else {
     763           0 :                         switch (stmt->param_bind[i].type) {
     764             :                                 case MYSQL_TYPE_DOUBLE:
     765           0 :                                         convert_to_double_ex(&data);
     766           0 :                                         float8store(*p, Z_DVAL_P(data));
     767           0 :                                         (*p) += 8;
     768           0 :                                         break;
     769             :                                 case MYSQL_TYPE_LONGLONG:
     770           0 :                                         if (Z_TYPE_P(data) == IS_STRING) {
     771           0 :                                                 goto send_string;
     772             :                                         }
     773             :                                         /* data has alreade been converted to long */
     774           0 :                                         int8store(*p, Z_LVAL_P(data));
     775           0 :                                         (*p) += 8;
     776           0 :                                         break;
     777             :                                 case MYSQL_TYPE_LONG:
     778           0 :                                         if (Z_TYPE_P(data) == IS_STRING) {
     779           0 :                                                 goto send_string;
     780             :                                         }
     781             :                                         /* data has alreade been converted to long */
     782           0 :                                         int4store(*p, Z_LVAL_P(data));
     783           0 :                                         (*p) += 4;
     784           0 :                                         break;
     785             :                                 case MYSQL_TYPE_LONG_BLOB:
     786           0 :                                         if (stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED) {
     787           0 :                                                 stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED;
     788             :                                         } else {
     789             :                                                 /* send_long_data() not called, send empty string */
     790           0 :                                                 *p = php_mysqlnd_net_store_length(*p, 0);
     791             :                                         }
     792           0 :                                         break;
     793             :                                 case MYSQL_TYPE_VAR_STRING:
     794             : send_string:
     795             :                                         {
     796           0 :                                                 size_t len = Z_STRLEN_P(data);
     797             :                                                 /* to is after p. The latter hasn't been moved */
     798           0 :                                                 *p = php_mysqlnd_net_store_length(*p, len);
     799           0 :                                                 memcpy(*p, Z_STRVAL_P(data), len);
     800           0 :                                                 (*p) += len;
     801             :                                         }
     802           0 :                                         break;
     803             :                                 default:
     804             :                                         /* Won't happen, but set to NULL */
     805           0 :                                         (buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
     806             :                                         break;
     807             :                         }
     808             :                 }
     809             :         }
     810           0 : }
     811             : /* }}} */
     812             : 
     813             : 
     814             : /* {{{ mysqlnd_stmt_execute_store_params */
     815             : static enum_func_status
     816           0 : mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p, size_t *buf_len  TSRMLS_DC)
     817             : {
     818           0 :         MYSQLND_STMT_DATA * stmt = s->data;
     819           0 :         unsigned int i = 0;
     820           0 :         zend_uchar * provided_buffer = *buf;
     821           0 :         size_t data_size = 0;
     822           0 :         zval **copies = NULL;/* if there are different types */
     823           0 :         enum_func_status ret = FAIL;
     824           0 :         int resend_types_next_time = 0;
     825             :         size_t null_byte_offset;
     826             : 
     827           0 :         DBG_ENTER("mysqlnd_stmt_execute_store_params");
     828             : 
     829             :         {
     830           0 :                 unsigned int null_count = (stmt->param_count + 7) / 8;
     831           0 :                 if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, null_count TSRMLS_CC)) {
     832           0 :                         SET_OOM_ERROR(*stmt->error_info);
     833           0 :                         goto end;
     834             :                 }
     835             :                 /* put `null` bytes */
     836           0 :                 null_byte_offset = *p - *buf;
     837           0 :                 memset(*p, 0, null_count);
     838           0 :                 *p += null_count;
     839             :         }
     840             : 
     841             : /* 1. Store type information */
     842             :         /*
     843             :           check if need to send the types even if stmt->send_types_to_server is 0. This is because
     844             :           if we send "i" (42) then the type will be int and the server will expect int. However, if next
     845             :           time we try to send > LONG_MAX, the conversion to string will send a string and the server
     846             :           won't expect it and interpret the value as 0. Thus we need to resend the types, if any such values
     847             :           occur, and force resend for the next execution.
     848             :         */
     849           0 :         if (FAIL == mysqlnd_stmt_execute_prepare_param_types(stmt, &copies, &resend_types_next_time TSRMLS_CC)) {
     850           0 :                 goto end;
     851             :         }
     852             : 
     853           0 :         int1store(*p, stmt->send_types_to_server);
     854           0 :         (*p)++;
     855             : 
     856           0 :         if (stmt->send_types_to_server) {
     857           0 :                 if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, stmt->param_count * 2 TSRMLS_CC)) {
     858           0 :                         SET_OOM_ERROR(*stmt->error_info);
     859           0 :                         goto end;
     860             :                 }
     861           0 :                 mysqlnd_stmt_execute_store_types(stmt, copies, p);
     862             :         }
     863             : 
     864           0 :         stmt->send_types_to_server = resend_types_next_time;
     865             : 
     866             : /* 2. Store data */
     867             :         /* 2.1 Calculate how much space we need */
     868           0 :         if (FAIL == mysqlnd_stmt_execute_calculate_param_values_size(stmt, &copies, &data_size TSRMLS_CC)) {
     869           0 :                 goto end;
     870             :         }
     871             : 
     872             :         /* 2.2 Enlarge the buffer, if needed */
     873           0 :         if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, data_size TSRMLS_CC)) {
     874           0 :                 SET_OOM_ERROR(*stmt->error_info);
     875           0 :                 goto end;
     876             :         }
     877             : 
     878             :         /* 2.3 Store the actual data */
     879           0 :         mysqlnd_stmt_execute_store_param_values(stmt, copies, *buf, p, null_byte_offset);
     880             : 
     881           0 :         ret = PASS;
     882             : end:
     883           0 :         mysqlnd_stmt_free_copies(stmt, copies TSRMLS_CC);
     884             : 
     885           0 :         DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"FAIL");
     886           0 :         DBG_RETURN(ret);
     887             : }
     888             : /* }}} */
     889             : 
     890             : 
     891             : /* {{{ mysqlnd_stmt_execute_generate_request */
     892             : enum_func_status
     893           0 : mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer TSRMLS_DC)
     894             : {
     895           0 :         MYSQLND_STMT_DATA * stmt = s->data;
     896           0 :         zend_uchar      *p = stmt->execute_cmd_buffer.buffer,
     897           0 :                                 *cmd_buffer = stmt->execute_cmd_buffer.buffer;
     898           0 :         size_t cmd_buffer_length = stmt->execute_cmd_buffer.length;
     899             :         enum_func_status ret;
     900             : 
     901           0 :         DBG_ENTER("mysqlnd_stmt_execute_generate_request");
     902             : 
     903           0 :         int4store(p, stmt->stmt_id);
     904           0 :         p += 4;
     905             : 
     906             :         /* flags is 4 bytes, we store just 1 */
     907           0 :         int1store(p, (zend_uchar) stmt->flags);
     908           0 :         p++;
     909             : 
     910             :         /* Make it all zero */
     911           0 :         int4store(p, 0); 
     912             : 
     913           0 :         int1store(p, 1); /* and send 1 for iteration count */
     914           0 :         p+= 4;
     915             : 
     916           0 :         ret = mysqlnd_stmt_execute_store_params(s, &cmd_buffer, &p, &cmd_buffer_length TSRMLS_CC);
     917             : 
     918           0 :         *free_buffer = (cmd_buffer != stmt->execute_cmd_buffer.buffer);
     919           0 :         *request_len = (p - cmd_buffer);
     920           0 :         *request = cmd_buffer;
     921           0 :         DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"FAIL");
     922           0 :         DBG_RETURN(ret);
     923             : }
     924             : /* }}} */
     925             : 
     926             : /*
     927             :  * Local variables:
     928             :  * tab-width: 4
     929             :  * c-basic-offset: 4
     930             :  * End:
     931             :  * vim600: noet sw=4 ts=4 fdm=marker
     932             :  * vim<600: noet sw=4 ts=4
     933             :  */

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:51 +0000 (2 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.