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