php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
mysql_statement.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: George Schlossnagle <george@omniti.com> |
14 | Wez Furlong <wez@php.net> |
15 | Johannes Schlueter <johannes@mysql.com> |
16 +----------------------------------------------------------------------+
17*/
18
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include "php.h"
24#include "php_ini.h"
25#include "ext/standard/info.h"
26#include "ext/pdo/php_pdo.h"
28#include "php_pdo_mysql.h"
29#include "php_pdo_mysql_int.h"
30
31#ifdef PDO_USE_MYSQLND
32# define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_mysqlnd(stmt)
33#else
34# define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_libmysql(stmt)
35#endif
36
37static void pdo_mysql_free_result(pdo_mysql_stmt *S)
38{
39 if (S->result) {
40#ifndef PDO_USE_MYSQLND
41 if (S->bound_result) {
42 /* We can't use stmt->column_count here, because it gets reset before the
43 * next_rowset handler is called. */
44 unsigned column_count = mysql_num_fields(S->result);
45 for (unsigned i = 0; i < column_count; i++) {
46 efree(S->bound_result[i].buffer);
47 }
48
49 efree(S->bound_result);
50 efree(S->out_null);
51 efree(S->out_length);
52 S->bound_result = NULL;
53 }
54#else
55 if (S->current_row) {
56 unsigned column_count = mysql_num_fields(S->result);
57 for (unsigned i = 0; i < column_count; i++) {
58 zval_ptr_dtor_nogc(&S->current_row[i]);
59 }
60 efree(S->current_row);
61 S->current_row = NULL;
62 }
63#endif
64 mysql_free_result(S->result);
65 S->result = NULL;
66 }
67}
68
69static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
70{
72
73 PDO_DBG_ENTER("pdo_mysql_stmt_dtor");
74 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
75
76 pdo_mysql_free_result(S);
77 if (S->einfo.errmsg) {
78 pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
79 S->einfo.errmsg = NULL;
80 }
81 if (S->stmt) {
82 mysql_stmt_close(S->stmt);
83 S->stmt = NULL;
84 }
85
86#ifndef PDO_USE_MYSQLND
87 if (S->params) {
88 efree(S->params);
89 }
90 if (S->in_null) {
91 efree(S->in_null);
92 }
93 if (S->in_length) {
94 efree(S->in_length);
95 }
96#endif
97
98 if (!S->done && !Z_ISUNDEF(stmt->database_object_handle)
99 && IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
100 && (!(OBJ_FLAGS(Z_OBJ(stmt->database_object_handle)) & IS_OBJ_FREE_CALLED))) {
101 while (mysql_more_results(S->H->server)) {
102 MYSQL_RES *res;
103 if (mysql_next_result(S->H->server) != 0) {
104 break;
105 }
106
107 res = mysql_store_result(S->H->server);
108 if (res) {
110 }
111 }
112 }
113
114 efree(S);
116}
117/* }}} */
118
119static void pdo_mysql_stmt_set_row_count(pdo_stmt_t *stmt) /* {{{ */
120{
122 zend_long row_count = (zend_long) mysql_stmt_affected_rows(S->stmt);
123 if (row_count != (zend_long)-1) {
124 stmt->row_count = row_count;
125 }
126}
127/* }}} */
128
129static int pdo_mysql_fill_stmt_from_result(pdo_stmt_t *stmt) /* {{{ */
130{
132 pdo_mysql_db_handle *H = S->H;
133 my_ulonglong row_count;
134 PDO_DBG_ENTER("pdo_mysql_fill_stmt_from_result");
135
136 row_count = mysql_affected_rows(H->server);
137 if (row_count == (my_ulonglong)-1) {
138 /* we either have a query that returned a result set or an error occurred
139 lets see if we have access to a result set */
140 if (!H->buffered) {
141 S->result = mysql_use_result(H->server);
142 } else {
143 S->result = mysql_store_result(H->server);
144 }
145 if (NULL == S->result) {
148 }
149
150 stmt->row_count = (zend_long) mysql_num_rows(S->result);
152 S->fields = mysql_fetch_fields(S->result);
153 } else {
154 /* this was a DML or DDL query (INSERT, UPDATE, DELETE, ... */
155 stmt->row_count = (zend_long) row_count;
156 }
157
159}
160/* }}} */
161
162static bool pdo_mysql_stmt_after_execute_prepared(pdo_stmt_t *stmt) {
164 pdo_mysql_db_handle *H = S->H;
165
166#ifdef PDO_USE_MYSQLND
167 /* For SHOW/DESCRIBE and others the column/field count is not available before execute. */
169 for (int i = 0; i < stmt->column_count; i++) {
171 }
172
173 S->result = mysqlnd_stmt_result_metadata(S->stmt);
174 if (S->result) {
175 S->fields = mysql_fetch_fields(S->result);
176 /* If buffered, pre-fetch all the data */
177 if (H->buffered) {
178 if (mysql_stmt_store_result(S->stmt)) {
180 return false;
181 }
182 }
183 }
184#else
185 /* figure out the result set format, if any */
186 S->result = mysql_stmt_result_metadata(S->stmt);
187 if (S->result) {
188 int calc_max_length = H->buffered && S->max_length == 1;
189 S->fields = mysql_fetch_fields(S->result);
190
192 S->bound_result = ecalloc(stmt->column_count, sizeof(MYSQL_BIND));
193 S->out_null = ecalloc(stmt->column_count, sizeof(my_bool));
194 S->out_length = ecalloc(stmt->column_count, sizeof(zend_ulong));
195
196 /* summon memory to hold the row */
197 for (int i = 0; i < stmt->column_count; i++) {
198 if (calc_max_length && S->fields[i].type == FIELD_TYPE_BLOB) {
199 my_bool on = 1;
201 calc_max_length = 0;
202 }
203 switch (S->fields[i].type) {
204 case FIELD_TYPE_INT24:
205 S->bound_result[i].buffer_length = MAX_MEDIUMINT_WIDTH + 1;
206 break;
207 case FIELD_TYPE_LONG:
208 S->bound_result[i].buffer_length = MAX_INT_WIDTH + 1;
209 break;
211 S->bound_result[i].buffer_length = MAX_BIGINT_WIDTH + 1;
212 break;
213 case FIELD_TYPE_TINY:
214 S->bound_result[i].buffer_length = MAX_TINYINT_WIDTH + 1;
215 break;
216 case FIELD_TYPE_SHORT:
217 S->bound_result[i].buffer_length = MAX_SMALLINT_WIDTH + 1;
218 break;
219 default:
220 S->bound_result[i].buffer_length =
221 S->fields[i].max_length? S->fields[i].max_length:
222 S->fields[i].length;
223 /* work-around for longtext and alike */
224 if (S->bound_result[i].buffer_length > H->max_buffer_size) {
225 S->bound_result[i].buffer_length = H->max_buffer_size;
226 }
227 }
228
229 /* there are cases where the length reported by mysql is too short.
230 * eg: when describing a table that contains an enum column. Since
231 * we have no way of knowing the true length either, we'll bump up
232 * our buffer size to a reasonable size, just in case */
233 if (S->fields[i].max_length == 0 && S->bound_result[i].buffer_length < 128 && MYSQL_TYPE_VAR_STRING) {
234 S->bound_result[i].buffer_length = 128;
235 }
236
237 S->out_length[i] = 0;
238
239 S->bound_result[i].buffer = emalloc(S->bound_result[i].buffer_length);
240 S->bound_result[i].is_null = &S->out_null[i];
241 S->bound_result[i].length = &S->out_length[i];
242 S->bound_result[i].buffer_type = MYSQL_TYPE_STRING;
243 }
244
245 if (mysql_stmt_bind_result(S->stmt, S->bound_result)) {
248 }
249
250 /* if buffered, pre-fetch all the data */
251 if (H->buffered) {
252 if (mysql_stmt_store_result(S->stmt)) {
255 }
256 }
257 }
258#endif
259
260 pdo_mysql_stmt_set_row_count(stmt);
261 return true;
262}
263
264#ifndef PDO_USE_MYSQLND
265static int pdo_mysql_stmt_execute_prepared_libmysql(pdo_stmt_t *stmt) /* {{{ */
266{
268
269 PDO_DBG_ENTER("pdo_mysql_stmt_execute_prepared_libmysql");
270
271 /* (re)bind the parameters */
272 if (mysql_stmt_bind_param(S->stmt, S->params) || mysql_stmt_execute(S->stmt)) {
273 if (S->params) {
274 memset(S->params, 0, S->num_params * sizeof(MYSQL_BIND));
275 }
277 if (mysql_stmt_errno(S->stmt) == 2057) {
278 /* CR_NEW_STMT_METADATA makes the statement unusable */
279 S->stmt = NULL;
280 }
282 }
283
284 PDO_DBG_RETURN(pdo_mysql_stmt_after_execute_prepared(stmt));
285}
286/* }}} */
287#endif
288
289#ifdef PDO_USE_MYSQLND
290static int pdo_mysql_stmt_execute_prepared_mysqlnd(pdo_stmt_t *stmt) /* {{{ */
291{
293
294 PDO_DBG_ENTER("pdo_mysql_stmt_execute_prepared_mysqlnd");
295
296 if (mysql_stmt_execute(S->stmt)) {
299 }
300
301 PDO_DBG_RETURN(pdo_mysql_stmt_after_execute_prepared(stmt));
302}
303/* }}} */
304#endif
305
306static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
307{
309 pdo_mysql_db_handle *H = S->H;
310 PDO_DBG_ENTER("pdo_mysql_stmt_execute");
311 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
312
313 /* ensure that we free any previous unfetched results */
314 pdo_mysql_free_result(S);
315 S->done = 0;
316
317 if (S->stmt) {
318 uint32_t num_bound_params =
319 stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0;
320 if (num_bound_params < (uint32_t) S->num_params) {
321 /* too few parameter bound */
322 PDO_DBG_ERR("too few parameters bound");
323 strcpy(stmt->error_code, "HY093");
325 }
326
328 }
329
333 }
334
335 PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt));
336}
337/* }}} */
338
339static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
340{
342 pdo_mysql_db_handle *H = S->H;
343 PDO_DBG_ENTER("pdo_mysql_stmt_next_rowset");
344 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
345
346 /* ensure that we free any previous unfetched results */
347 pdo_mysql_free_result(S);
348
349 if (S->stmt) {
351 if (mysql_stmt_next_result(S->stmt)) {
353 S->done = 1;
355 }
356 PDO_DBG_RETURN(pdo_mysql_stmt_after_execute_prepared(stmt));
357 } else {
358 if (mysql_next_result(H->server)) {
360 S->done = 1;
362 }
363 PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt));
364 }
365}
366/* }}} */
367
368
369static const char * const pdo_param_event_names[] =
370{
371 "PDO_PARAM_EVT_ALLOC",
372 "PDO_PARAM_EVT_FREE",
373 "PDO_PARAM_EVT_EXEC_PRE",
374 "PDO_PARAM_EVT_EXEC_POST",
375 "PDO_PARAM_EVT_FETCH_PRE",
376 "PDO_PARAM_EVT_FETCH_POST",
377 "PDO_PARAM_EVT_NORMALIZE",
378};
379
380#ifndef PDO_USE_MYSQLND
381static unsigned char libmysql_false_buffer = 0;
382static unsigned char libmysql_true_buffer = 1;
383#endif
384
385static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type) /* {{{ */
386{
387 zval *parameter;
388#ifndef PDO_USE_MYSQLND
390#endif
392
393 PDO_DBG_ENTER("pdo_mysql_stmt_param_hook");
394 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
395 PDO_DBG_INF_FMT("event = %s", pdo_param_event_names[event_type]);
396 if (S->stmt && param->is_param) {
397 switch (event_type) {
399 /* sanity check parameter number range */
400 if (param->paramno < 0 || param->paramno >= S->num_params) {
401 strcpy(stmt->error_code, "HY093");
403 }
404
405#ifndef PDO_USE_MYSQLND
406 b = &S->params[param->paramno];
407 param->driver_data = b;
408 b->is_null = &S->in_null[param->paramno];
409 b->length = &S->in_length[param->paramno];
410 /* recall how many parameters have been provided */
411#endif
413
415 if (!Z_ISREF(param->parameter)) {
416 parameter = &param->parameter;
417 } else {
418 parameter = Z_REFVAL(param->parameter);
419 }
420
421#ifdef PDO_USE_MYSQLND
422 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL || (Z_TYPE_P(parameter) == IS_NULL)) {
423 mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_NULL);
425 }
426#else
427 b = (PDO_MYSQL_PARAM_BIND*)param->driver_data;
428 *b->is_null = 0;
429 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL || Z_TYPE_P(parameter) == IS_NULL) {
430 *b->is_null = 1;
431 b->buffer_type = MYSQL_TYPE_STRING;
432 b->buffer = NULL;
433 b->buffer_length = 0;
434 *b->length = 0;
436 }
437#endif /* PDO_USE_MYSQLND */
438
439 switch (PDO_PARAM_TYPE(param->param_type)) {
440 case PDO_PARAM_STMT:
442 case PDO_PARAM_LOB:
443 PDO_DBG_INF("PDO_PARAM_LOB");
444 if (!Z_ISREF(param->parameter)) {
445 parameter = &param->parameter;
446 } else {
447 parameter = Z_REFVAL(param->parameter);
448 }
449 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
450 php_stream *stm = NULL;
451 php_stream_from_zval_no_verify(stm, parameter);
452 if (stm) {
454 zval_ptr_dtor(parameter);
455 ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
456 } else {
457 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
458 return 0;
459 }
460 }
461 /* fall through */
462
463 default:
464 ;
465 }
466
467#ifdef PDO_USE_MYSQLND
468 /* Is it really correct to check the zval's type? - But well, that's what the old code below does, too */
469 PDO_DBG_INF_FMT("param->parameter->type=%d", Z_TYPE(param->parameter));
470 if (!Z_ISREF(param->parameter)) {
471 parameter = &param->parameter;
472 } else {
473 parameter = Z_REFVAL(param->parameter);
474 }
475 switch (Z_TYPE_P(parameter)) {
476 case IS_STRING:
477 mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_VAR_STRING);
478 break;
479 case IS_LONG:
480#if SIZEOF_ZEND_LONG==8
481 mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_LONGLONG);
482#elif SIZEOF_ZEND_LONG==4
483 mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_LONG);
484#endif /* SIZEOF_LONG */
485 break;
486 case IS_TRUE:
487 case IS_FALSE:
488 mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_TINY);
489 break;
490 case IS_DOUBLE:
491 mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_DOUBLE);
492 break;
493 default:
495 }
496
498#else
499 PDO_DBG_INF_FMT("param->parameter->type=%d", Z_TYPE(param->parameter));
500 if (!Z_ISREF(param->parameter)) {
501 parameter = &param->parameter;
502 } else {
503 parameter = Z_REFVAL(param->parameter);
504 }
505 switch (Z_TYPE_P(parameter)) {
506 case IS_STRING:
507 b->buffer_type = MYSQL_TYPE_STRING;
508 b->buffer = Z_STRVAL_P(parameter);
509 b->buffer_length = Z_STRLEN_P(parameter);
510 *b->length = Z_STRLEN_P(parameter);
512
513 case IS_FALSE:
514 b->buffer_type = MYSQL_TYPE_TINY;
515 b->buffer = &libmysql_false_buffer;
517
518 case IS_TRUE:
519 b->buffer_type = MYSQL_TYPE_TINY;
520 b->buffer = &libmysql_true_buffer;
522
523 case IS_LONG:
524 b->buffer_type = MYSQL_TYPE_LONG;
525 b->buffer = &Z_LVAL_P(parameter);
527
528 case IS_DOUBLE:
529 b->buffer_type = MYSQL_TYPE_DOUBLE;
530 b->buffer = &Z_DVAL_P(parameter);
532
533 default:
535 }
536#endif /* PDO_USE_MYSQLND */
542 /* do nothing */
543 break;
544 }
545 }
546
548}
549/* }}} */
550
551static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, zend_long offset) /* {{{ */
552{
554
555 if (!S->result) {
557 }
558
559#ifdef PDO_USE_MYSQLND
560 bool fetched_anything;
561
562 PDO_DBG_ENTER("pdo_mysql_stmt_fetch");
563 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
564 if (S->stmt) {
565 if (FAIL == mysqlnd_stmt_fetch(S->stmt, &fetched_anything) || !fetched_anything) {
568 }
569
571 }
572
573 zval *row_data;
574 if (mysqlnd_fetch_row_zval(S->result, &row_data, &fetched_anything) == FAIL) {
577 }
578
579 if (!fetched_anything) {
581 }
582
583 if (!S->current_row) {
584 S->current_row = ecalloc(stmt->column_count, sizeof(zval));
585 }
586 for (unsigned i = 0; i < stmt->column_count; i++) {
587 zval_ptr_dtor_nogc(&S->current_row[i]);
588 ZVAL_COPY_VALUE(&S->current_row[i], &row_data[i]);
589 }
591#else
592 int ret;
593
594 if (S->stmt) {
595 ret = mysql_stmt_fetch(S->stmt);
596
597# ifdef MYSQL_DATA_TRUNCATED
598 if (ret == MYSQL_DATA_TRUNCATED) {
599 ret = 0;
600 }
601# endif
602
603 if (ret) {
604 if (ret != MYSQL_NO_DATA) {
606 }
608 }
609
611 }
612
613 if ((S->current_data = mysql_fetch_row(S->result)) == NULL) {
614 if (!S->H->buffered && mysql_errno(S->H->server)) {
616 }
618 }
619
620 S->current_lengths = mysql_fetch_lengths(S->result);
622#endif /* PDO_USE_MYSQLND */
623}
624/* }}} */
625
626static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
627{
629 struct pdo_column_data *cols = stmt->columns;
630 int i;
631
632 PDO_DBG_ENTER("pdo_mysql_stmt_describe");
633 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
634 if (!S->result) {
636 }
637
638 if (colno >= stmt->column_count) {
639 /* error invalid column */
641 }
642
643 /* fetch all on demand, this seems easiest
644 ** if we've been here before bail out
645 */
646 if (cols[0].name) {
648 }
649 for (i = 0; i < stmt->column_count; i++) {
650
651 if (S->H->fetch_table_names) {
652 cols[i].name = strpprintf(0, "%s.%s", S->fields[i].table, S->fields[i].name);
653 } else {
654#ifdef PDO_USE_MYSQLND
655 cols[i].name = zend_string_copy(S->fields[i].sname);
656#else
657 cols[i].name = zend_string_init(S->fields[i].name, S->fields[i].name_length, 0);
658#endif
659 }
660
661 cols[i].precision = S->fields[i].decimals;
662 cols[i].maxlen = S->fields[i].length;
663 }
665}
666/* }}} */
667
668static int pdo_mysql_stmt_get_col(
669 pdo_stmt_t *stmt, int colno, zval *result, enum pdo_param_type *type) /* {{{ */
670{
672
673 PDO_DBG_ENTER("pdo_mysql_stmt_get_col");
674 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
675 if (!S->result) {
677 }
678
679 if (colno >= stmt->column_count) {
680 /* error invalid column */
682 }
683#ifdef PDO_USE_MYSQLND
684 if (S->stmt) {
685 ZVAL_COPY(result, &S->stmt->data->result_bind[colno].zv);
686 } else {
687 ZVAL_COPY(result, &S->current_row[colno]);
688 }
690#else
691 if (S->stmt) {
692 if (S->out_null[colno]) {
694 }
695
696 size_t length = S->out_length[colno];
697 if (length > S->bound_result[colno].buffer_length) {
698 /* mysql lied about the column width */
699 strcpy(stmt->error_code, "01004"); /* truncated */
700 length = S->out_length[colno] = S->bound_result[colno].buffer_length;
701 }
702 ZVAL_STRINGL_FAST(result, S->bound_result[colno].buffer, length);
704 }
705
706 if (S->current_data == NULL) {
708 }
709 if (S->current_data[colno]) {
710 ZVAL_STRINGL_FAST(result, S->current_data[colno], S->current_lengths[colno]);
711 }
713#endif
714} /* }}} */
715
716static char *type_to_name_native(int type) /* {{{ */
717{
718#define PDO_MYSQL_NATIVE_TYPE_NAME(x) case FIELD_TYPE_##x: return #x;
719
720 switch (type) {
723#ifdef FIELD_TYPE_TINY
725#endif
726#ifdef FIELD_TYPE_BIT
728#endif
736#ifdef FIELD_TYPE_NEWDECIMAL
738#endif
739#ifdef FIELD_TYPE_GEOMETRY
741#endif
743#ifdef FIELD_TYPE_YEAR
745#endif
749#ifdef FIELD_TYPE_NEWDATE
751#endif
755 PDO_MYSQL_NATIVE_TYPE_NAME(MEDIUM_BLOB)
759 default:
760 return NULL;
761 }
762#undef PDO_MYSQL_NATIVE_TYPE_NAME
763} /* }}} */
764
765static int pdo_mysql_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value) /* {{{ */
766{
768 const MYSQL_FIELD *F;
769 zval flags;
770 char *str;
771
772 PDO_DBG_ENTER("pdo_mysql_stmt_col_meta");
773 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
774 if (!S->result) {
776 }
777 if (colno >= stmt->column_count) {
778 /* error invalid column */
780 }
781
784
785 F = S->fields + colno;
786
787 if (F->def) {
788 add_assoc_string(return_value, "mysql:def", F->def);
789 }
790 if (IS_NOT_NULL(F->flags)) {
791 add_next_index_string(&flags, "not_null");
792 }
793 if (IS_PRI_KEY(F->flags)) {
794 add_next_index_string(&flags, "primary_key");
795 }
796 if (F->flags & MULTIPLE_KEY_FLAG) {
797 add_next_index_string(&flags, "multiple_key");
798 }
799 if (F->flags & UNIQUE_KEY_FLAG) {
800 add_next_index_string(&flags, "unique_key");
801 }
802 if (IS_BLOB(F->flags)) {
804 }
805 str = type_to_name_native(F->type);
806 if (str) {
807 add_assoc_string(return_value, "native_type", str);
808 }
809
810 enum pdo_param_type param_type;
811 switch (F->type) {
812 case MYSQL_TYPE_BIT:
813 case MYSQL_TYPE_YEAR:
814 case MYSQL_TYPE_TINY:
815 case MYSQL_TYPE_SHORT:
816 case MYSQL_TYPE_INT24:
817 case MYSQL_TYPE_LONG:
818#if SIZEOF_ZEND_LONG==8
820#endif
821 param_type = PDO_PARAM_INT;
822 break;
823 default:
824 param_type = PDO_PARAM_STR;
825 break;
826 }
827 add_assoc_long(return_value, "pdo_type", param_type);
828
829 add_assoc_zval(return_value, "flags", &flags);
830 add_assoc_string(return_value, "table", (char *) (F->table?F->table : ""));
831
833} /* }}} */
834
835static int pdo_mysql_stmt_cursor_closer(pdo_stmt_t *stmt) /* {{{ */
836{
838
839 PDO_DBG_ENTER("pdo_mysql_stmt_cursor_closer");
840 PDO_DBG_INF_FMT("stmt=%p", S->stmt);
841
842 S->done = 1;
843 pdo_mysql_free_result(S);
844 if (S->stmt) {
846 }
847
848 while (mysql_more_results(S->H->server)) {
849 MYSQL_RES *res;
850 if (mysql_next_result(S->H->server) != 0) {
853 }
854 res = mysql_store_result(S->H->server);
855 if (res) {
857 }
858 }
860}
861/* }}} */
862
864 pdo_mysql_stmt_dtor,
865 pdo_mysql_stmt_execute,
866 pdo_mysql_stmt_fetch,
867 pdo_mysql_stmt_describe,
868 pdo_mysql_stmt_get_col,
869 pdo_mysql_stmt_param_hook,
870 NULL, /* set_attr */
871 NULL, /* get_attr */
872 pdo_mysql_stmt_col_meta,
873 pdo_mysql_stmt_next_rowset,
874 pdo_mysql_stmt_cursor_closer
875};
zend_ffi_type * type
Definition ffi.c:3812
zend_string * res
Definition ffi.c:4692
memset(ptr, 0, type->size)
#define F
Definition encoding.c:235
#define BIT(A)
Definition file.h:370
zend_long offset
#define NULL
Definition gdcache.h:45
#define S(s, l, r)
Definition hash_gost.c:121
#define SUCCESS
Definition hash_sha3.c:261
#define SET(n)
Definition md5.c:172
#define H(x, y, z)
Definition md5.c:146
#define pdo_mysql_stmt_execute_prepared(stmt)
const struct pdo_stmt_methods mysql_stmt_methods
#define PDO_MYSQL_NATIVE_TYPE_NAME(x)
#define mysqlnd_stmt_bind_one_result(s, no)
Definition mysqlnd.h:232
#define mysqlnd_fetch_row_zval(result, row_ptr, fetched)
Definition mysqlnd.h:105
#define mysqlnd_stmt_fetch(stmt, fetched)
Definition mysqlnd.h:244
#define mysqlnd_stmt_result_metadata(stmt)
Definition mysqlnd.h:233
#define mysqlnd_stmt_bind_one_param(stmt, n, z, t)
Definition mysqlnd.h:227
#define UNIQUE_KEY_FLAG
#define IS_BLOB(n)
#define IS_NOT_NULL(n)
#define FIELD_TYPE_LONG
#define FIELD_TYPE_LONGLONG
#define MULTIPLE_KEY_FLAG
#define IS_PRI_KEY(n)
#define FIELD_TYPE_INT24
#define FIELD_TYPE_BLOB
@ STMT_ATTR_UPDATE_MAX_LENGTH
#define FIELD_TYPE_SHORT
@ MYSQL_TYPE_LONGLONG
@ MYSQL_TYPE_VAR_STRING
@ MYSQL_TYPE_TINY
@ MYSQL_TYPE_STRING
@ MYSQL_TYPE_NULL
@ MYSQL_TYPE_LONG
@ MYSQL_TYPE_BIT
@ MYSQL_TYPE_DOUBLE
@ MYSQL_TYPE_SHORT
@ MYSQL_TYPE_INT24
@ MYSQL_TYPE_YEAR
#define FIELD_TYPE_TINY
#define MYSQL_RES
#define mysql_stmt_store_result(s)
#define mysql_stmt_execute(s)
#define mysql_stmt_attr_set(s, a, v)
#define mysql_use_result(r)
#define my_ulonglong
#define mysql_free_result(r)
#define mysql_fetch_row(r)
#define mysql_stmt_bind_param(s, b)
#define mysql_num_rows(r)
#define my_bool
#define mysql_stmt_errno(s)
#define mysql_store_result(r)
#define mysql_more_results(r)
#define mysql_affected_rows(r)
#define mysql_fetch_lengths(r)
#define mysql_stmt_free_result(s)
#define MYSQL_DATA_TRUNCATED
#define mysql_stmt_close(s)
#define MYSQL_FIELD
#define mysql_real_query(r, a, b)
#define mysql_stmt_field_count(s)
#define mysql_stmt_bind_result(s, b)
#define mysql_errno(r)
#define MYSQL_NO_DATA
#define mysql_stmt_affected_rows(s)
#define mysql_next_result(r)
#define mysql_num_fields(r)
#define mysql_stmt_result_metadata(s)
#define mysql_stmt_next_result(s)
#define mysql_fetch_fields(r)
#define TIME
Definition parse_date.c:48
#define DATE
Definition parse_date.c:49
#define STRING(a)
void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, pdo_error_type sqlstate, const char *supp)
Definition pdo_dbh.c:68
PDO_API void php_pdo_stmt_set_column_count(pdo_stmt_t *stmt, int new_count)
Definition pdo_stmt.c:195
struct _pdo_stmt_t pdo_stmt_t
pdo_param_type
@ PDO_PARAM_LOB
@ PDO_PARAM_INT
@ PDO_PARAM_STMT
@ PDO_PARAM_NULL
@ PDO_PARAM_STR
pdo_param_event
@ PDO_PARAM_EVT_ALLOC
@ PDO_PARAM_EVT_EXEC_PRE
@ PDO_PARAM_EVT_FETCH_POST
@ PDO_PARAM_EVT_NORMALIZE
@ PDO_PARAM_EVT_FETCH_PRE
@ PDO_PARAM_EVT_EXEC_POST
@ PDO_PARAM_EVT_FREE
pdo_fetch_orientation
#define PDO_PARAM_TYPE(x)
#define PDO_DBG_RETURN(value)
#define PDO_MYSQL_PARAM_BIND
#define pdo_mysql_error_stmt(s)
struct _php_stream php_stream
Definition php_streams.h:96
#define PHP_STREAM_COPY_ALL
#define php_stream_copy_to_mem(src, maxlen, persistent)
#define php_stream_from_zval_no_verify(xstr, pzval)
#define strpprintf
Definition spprintf.h:30
#define FAIL(...)
zend_string * active_query_string
pdo_error_type error_code
HashTable * bound_params
struct pdo_column_data * columns
zend_long row_count
pdo_dbh_t * dbh
zend_ulong precision
zend_string * name
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
#define ZVAL_STRINGL_FAST(z, s, l)
Definition zend_API.h:983
#define array_init(arg)
Definition zend_API.h:537
#define ecalloc(nmemb, size)
Definition zend_alloc.h:158
#define efree(ptr)
Definition zend_alloc.h:155
#define pefree(ptr, persistent)
Definition zend_alloc.h:191
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
#define EG(v)
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
struct _zend_string zend_string
#define IS_OBJ_VALID(o)
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_EMPTY_ALLOC()
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define IS_TRUE
Definition zend_types.h:603
#define ZVAL_STR(z, s)
#define IS_FALSE
Definition zend_types.h:602
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define IS_STRING
Definition zend_types.h:606
#define IS_RESOURCE
Definition zend_types.h:609
#define IS_OBJ_FREE_CALLED
Definition zend_types.h:829
#define IS_DOUBLE
Definition zend_types.h:605
#define Z_ISUNDEF(zval)
Definition zend_types.h:956
#define Z_REFVAL(zval)
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define IS_NULL
Definition zend_types.h:601
@ FAILURE
Definition zend_types.h:61
#define IS_LONG
Definition zend_types.h:604
#define Z_OBJ_HANDLE(zval)
Definition zend_types.h:998
#define ZVAL_COPY(z, v)
#define Z_ISREF(zval)
Definition zend_types.h:953
#define Z_TYPE(zval)
Definition zend_types.h:659
#define Z_DVAL_P(zval_p)
Definition zend_types.h:969
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
#define ZVAL_COPY_VALUE(z, v)
#define OBJ_FLAGS(obj)
Definition zend_types.h:831
#define Z_OBJ(zval)
Definition zend_types.h:989
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval * return_value
zend_string * name
bool result
zval * ret