php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
pgsql_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 | Authors: Edin Kadribasic <edink@emini.dk> |
14 | Ilia Alshanestsky <ilia@prohost.org> |
15 | Wez Furlong <wez@php.net> |
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_pgsql.h"
29#include "php_pdo_pgsql_int.h"
30#ifdef HAVE_NETINET_IN_H
31#include <netinet/in.h>
32#endif
33
34/* from postgresql/src/include/catalog/pg_type.h */
35#define BOOLLABEL "bool"
36#define BOOLOID 16
37#define BYTEALABEL "bytea"
38#define BYTEAOID 17
39#define DATELABEL "date"
40#define DATEOID 1082
41#define INT2LABEL "int2"
42#define INT2OID 21
43#define INT4LABEL "int4"
44#define INT4OID 23
45#define INT8LABEL "int8"
46#define INT8OID 20
47#define OIDOID 26
48#define TEXTLABEL "text"
49#define TEXTOID 25
50#define TIMESTAMPLABEL "timestamp"
51#define TIMESTAMPOID 1114
52#define VARCHARLABEL "varchar"
53#define VARCHAROID 1043
54#define FLOAT4LABEL "float4"
55#define FLOAT4OID 700
56#define FLOAT8LABEL "float8"
57#define FLOAT8OID 701
58
59
60
61static int pgsql_stmt_dtor(pdo_stmt_t *stmt)
62{
64 bool server_obj_usable = !Z_ISUNDEF(stmt->database_object_handle)
65 && IS_OBJ_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE(stmt->database_object_handle)])
67
68 if (S->result) {
69 /* free the resource */
70 PQclear(S->result);
71 S->result = NULL;
72 }
73
74 if (S->stmt_name) {
75 if (S->is_prepared && server_obj_usable) {
77 PGresult *res;
78#ifndef HAVE_PQCLOSEPREPARED
79 // TODO (??) libpq does not support close statement protocol < postgres 17
80 // check if we can circumvent this.
81 char *q = NULL;
82 spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
83 res = PQexec(H->server, q);
84 efree(q);
85#else
86 res = PQclosePrepared(H->server, S->stmt_name);
87#endif
88 if (res) {
89 PQclear(res);
90 }
91 }
92 efree(S->stmt_name);
93 S->stmt_name = NULL;
94 }
95 if (S->param_lengths) {
96 efree(S->param_lengths);
97 S->param_lengths = NULL;
98 }
99 if (S->param_values) {
100 efree(S->param_values);
101 S->param_values = NULL;
102 }
103 if (S->param_formats) {
104 efree(S->param_formats);
105 S->param_formats = NULL;
106 }
107 if (S->param_types) {
108 efree(S->param_types);
109 S->param_types = NULL;
110 }
111 if (S->query) {
112 zend_string_release(S->query);
113 S->query = NULL;
114 }
115
116 if (S->cursor_name) {
117 if (server_obj_usable) {
118 pdo_pgsql_db_handle *H = S->H;
119 char *q = NULL;
120 PGresult *res;
121
122 spprintf(&q, 0, "CLOSE %s", S->cursor_name);
123 res = PQexec(H->server, q);
124 efree(q);
125 if (res) PQclear(res);
126 }
127 efree(S->cursor_name);
128 S->cursor_name = NULL;
129 }
130
131 if(S->cols) {
132 efree(S->cols);
133 S->cols = NULL;
134 }
135 efree(S);
136 stmt->driver_data = NULL;
137 return 1;
138}
139
140static int pgsql_stmt_execute(pdo_stmt_t *stmt)
141{
143 pdo_pgsql_db_handle *H = S->H;
144 ExecStatusType status;
145
146 bool in_trans = stmt->dbh->methods->in_transaction(stmt->dbh);
147
148 /* ensure that we free any previous unfetched results */
149 if(S->result) {
150 PQclear(S->result);
151 S->result = NULL;
152 }
153
154 S->current_row = 0;
155
156 if (S->cursor_name) {
157 char *q = NULL;
158
159 if (S->is_prepared) {
160 spprintf(&q, 0, "CLOSE %s", S->cursor_name);
161 PQclear(PQexec(H->server, q));
162 efree(q);
163 }
164
165 spprintf(&q, 0, "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s", S->cursor_name, ZSTR_VAL(stmt->active_query_string));
166 S->result = PQexec(H->server, q);
167 efree(q);
168
169 /* check if declare failed */
170 status = PQresultStatus(S->result);
171 if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
173 return 0;
174 }
175 PQclear(S->result);
176
177 /* the cursor was declared correctly */
178 S->is_prepared = 1;
179
180 /* fetch to be able to get the number of tuples later, but don't advance the cursor pointer */
181 spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name);
182 S->result = PQexec(H->server, q);
183 efree(q);
184 } else if (S->stmt_name) {
185 /* using a prepared statement */
186
187 if (!S->is_prepared) {
188stmt_retry:
189 /* we deferred the prepare until now, because we didn't
190 * know anything about the parameter types; now we do */
191 S->result = PQprepare(H->server, S->stmt_name, ZSTR_VAL(S->query),
192 stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
193 S->param_types);
194 status = PQresultStatus(S->result);
195 switch (status) {
196 case PGRES_COMMAND_OK:
197 case PGRES_TUPLES_OK:
198 /* it worked */
199 S->is_prepared = 1;
200 PQclear(S->result);
201 break;
202 default: {
203 char *sqlstate = pdo_pgsql_sqlstate(S->result);
204 /* 42P05 means that the prepared statement already existed. this can happen if you use
205 * a connection pooling software line pgpool which doesn't close the db-connection once
206 * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
207 * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
208 * deallocate it and retry ONCE (thies 2005.12.15)
209 */
210 if (sqlstate && !strcmp(sqlstate, "42P05")) {
211 PGresult *res;
212#ifndef HAVE_PQCLOSEPREPARED
213 char buf[100]; /* stmt_name == "pdo_crsr_%08x" */
214 snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
215 res = PQexec(H->server, buf);
216#else
217 res = PQclosePrepared(H->server, S->stmt_name);
218#endif
219 if (res) {
220 PQclear(res);
221 }
222 goto stmt_retry;
223 } else {
225 return 0;
226 }
227 }
228 }
229 }
230 S->result = PQexecPrepared(H->server, S->stmt_name,
231 stmt->bound_params ?
232 zend_hash_num_elements(stmt->bound_params) :
233 0,
234 (const char**)S->param_values,
235 S->param_lengths,
236 S->param_formats,
237 0);
238 } else if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED) {
239 /* execute query with parameters */
240 S->result = PQexecParams(H->server, ZSTR_VAL(S->query),
241 stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
242 S->param_types,
243 (const char**)S->param_values,
244 S->param_lengths,
245 S->param_formats,
246 0);
247 } else {
248 /* execute plain query (with embedded parameters) */
249 S->result = PQexec(H->server, ZSTR_VAL(stmt->active_query_string));
250 }
251 status = PQresultStatus(S->result);
252
253 if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
255 return 0;
256 }
257
258 stmt->column_count = (int) PQnfields(S->result);
259 if (S->cols == NULL) {
260 S->cols = ecalloc(stmt->column_count, sizeof(pdo_pgsql_column));
261 }
262
263 if (status == PGRES_COMMAND_OK) {
264 stmt->row_count = ZEND_ATOL(PQcmdTuples(S->result));
265 H->pgoid = PQoidValue(S->result);
266 } else {
267 stmt->row_count = (zend_long)PQntuples(S->result);
268 }
269
270 if (in_trans && !stmt->dbh->methods->in_transaction(stmt->dbh)) {
272 }
273
274 return 1;
275}
276
277static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
278 enum pdo_param_event event_type)
279{
281
282 if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED && param->is_param) {
283 switch (event_type) {
285 if (param->driver_data) {
286 efree(param->driver_data);
287 }
288 break;
289
291 /* decode name from $1, $2 into 0, 1 etc. */
292 if (param->name) {
293 if (ZSTR_VAL(param->name)[0] == '$') {
294 param->paramno = ZEND_ATOL(ZSTR_VAL(param->name) + 1);
295 } else {
296 /* resolve parameter name to rewritten name */
297 zend_string *namevar;
298
299 if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map,
300 param->name)) != NULL) {
301 param->paramno = ZEND_ATOL(ZSTR_VAL(namevar) + 1);
302 param->paramno--;
303 } else {
304 pdo_pgsql_error_stmt_msg(stmt, 0, "HY093", ZSTR_VAL(param->name));
305 return 0;
306 }
307 }
308 }
309 break;
310
312 if (!stmt->bound_param_map) {
313 return 1;
314 }
315 if (!zend_hash_index_exists(stmt->bound_param_map, param->paramno)) {
316 pdo_pgsql_error_stmt_msg(stmt, 0, "HY093", "parameter was not defined");
317 return 0;
318 }
323 /* work is handled by EVT_NORMALIZE */
324 return 1;
325
327 if (!stmt->bound_param_map) {
328 return 1;
329 }
330 if (!S->param_values) {
331 S->param_values = ecalloc(
332 zend_hash_num_elements(stmt->bound_param_map),
333 sizeof(char*));
334 S->param_lengths = ecalloc(
335 zend_hash_num_elements(stmt->bound_param_map),
336 sizeof(int));
337 S->param_formats = ecalloc(
338 zend_hash_num_elements(stmt->bound_param_map),
339 sizeof(int));
340 S->param_types = ecalloc(
341 zend_hash_num_elements(stmt->bound_param_map),
342 sizeof(Oid));
343 }
344 if (param->paramno >= 0) {
345 zval *parameter;
346
347 /*
348 if (param->paramno >= zend_hash_num_elements(stmt->bound_params)) {
349 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
350 return 0;
351 }
352 */
353
354 if (Z_ISREF(param->parameter)) {
355 parameter = Z_REFVAL(param->parameter);
356 } else {
357 parameter = &param->parameter;
358 }
359
360 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB &&
361 Z_TYPE_P(parameter) == IS_RESOURCE) {
362 php_stream *stm;
363 php_stream_from_zval_no_verify(stm, parameter);
364 if (stm) {
366 struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
367 pdo_pgsql_bound_param *P = param->driver_data;
368
369 if (P == NULL) {
370 P = ecalloc(1, sizeof(*P));
371 param->driver_data = P;
372 }
373 P->oid = htonl(self->oid);
374 S->param_values[param->paramno] = (char*)&P->oid;
375 S->param_lengths[param->paramno] = sizeof(P->oid);
376 S->param_formats[param->paramno] = 1;
377 S->param_types[param->paramno] = OIDOID;
378 return 1;
379 } else {
381 if (str != NULL) {
382 ZVAL_STR(parameter, str);
383 } else {
384 ZVAL_EMPTY_STRING(parameter);
385 }
386 }
387 } else {
388 /* expected a stream resource */
389 pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
390 return 0;
391 }
392 }
393
394 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL ||
395 Z_TYPE_P(parameter) == IS_NULL) {
396 S->param_values[param->paramno] = NULL;
397 S->param_lengths[param->paramno] = 0;
398 } else if (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE) {
399 S->param_values[param->paramno] = Z_TYPE_P(parameter) == IS_TRUE ? "t" : "f";
400 S->param_lengths[param->paramno] = 1;
401 S->param_formats[param->paramno] = 0;
402 } else {
403 convert_to_string(parameter);
404 S->param_values[param->paramno] = Z_STRVAL_P(parameter);
405 S->param_lengths[param->paramno] = Z_STRLEN_P(parameter);
406 S->param_formats[param->paramno] = 0;
407 }
408
409 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
410 S->param_types[param->paramno] = 0;
411 S->param_formats[param->paramno] = 1;
412 } else {
413 S->param_types[param->paramno] = 0;
414 }
415 }
416 break;
417 }
418 } else if (param->is_param && event_type == PDO_PARAM_EVT_NORMALIZE) {
419 /* We need to manually convert to a pg native boolean value */
420 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
421 ((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
422 const char *s = zend_is_true(&param->parameter) ? "t" : "f";
423 param->param_type = PDO_PARAM_STR;
424 zval_ptr_dtor(&param->parameter);
425 ZVAL_STRINGL(&param->parameter, s, 1);
426 }
427 }
428 return 1;
429}
430
431static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
433{
435
436 if (S->cursor_name) {
437 char *ori_str = NULL;
438 char *q = NULL;
439 ExecStatusType status;
440
441 switch (ori) {
442 case PDO_FETCH_ORI_NEXT: spprintf(&ori_str, 0, "NEXT"); break;
443 case PDO_FETCH_ORI_PRIOR: spprintf(&ori_str, 0, "BACKWARD"); break;
444 case PDO_FETCH_ORI_FIRST: spprintf(&ori_str, 0, "FIRST"); break;
445 case PDO_FETCH_ORI_LAST: spprintf(&ori_str, 0, "LAST"); break;
446 case PDO_FETCH_ORI_ABS: spprintf(&ori_str, 0, "ABSOLUTE " ZEND_LONG_FMT, offset); break;
447 case PDO_FETCH_ORI_REL: spprintf(&ori_str, 0, "RELATIVE " ZEND_LONG_FMT, offset); break;
448 default:
449 return 0;
450 }
451
452 if(S->result) {
453 PQclear(S->result);
454 S->result = NULL;
455 }
456
457 spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name);
458 efree(ori_str);
459 S->result = PQexec(S->H->server, q);
460 efree(q);
461 status = PQresultStatus(S->result);
462
463 if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
465 return 0;
466 }
467
468 if (PQntuples(S->result)) {
469 S->current_row = 1;
470 return 1;
471 } else {
472 return 0;
473 }
474 } else {
475 if (S->current_row < stmt->row_count) {
476 S->current_row++;
477 return 1;
478 } else {
479 return 0;
480 }
481 }
482}
483
484static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno)
485{
487 struct pdo_column_data *cols = stmt->columns;
488 char *str;
489
490 if (!S->result) {
491 return 0;
492 }
493
494 str = PQfname(S->result, colno);
495 cols[colno].name = zend_string_init(str, strlen(str), 0);
496 cols[colno].maxlen = PQfsize(S->result, colno);
497 cols[colno].precision = PQfmod(S->result, colno);
498 S->cols[colno].pgsql_type = PQftype(S->result, colno);
499
500 return 1;
501}
502
503static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo_param_type *type)
504{
506 if (!S->result) {
507 return 0;
508 }
509
510 /* We have already increased count by 1 in pgsql_stmt_fetch() */
511 if (PQgetisnull(S->result, S->current_row - 1, colno)) { /* Check if we got NULL */
513 } else {
514 char *ptr = PQgetvalue(S->result, S->current_row - 1, colno);
515 size_t len = PQgetlength(S->result, S->current_row - 1, colno);
516
517 switch (S->cols[colno].pgsql_type) {
518 case BOOLOID:
519 ZVAL_BOOL(result, *ptr == 't');
520 break;
521
522 case INT2OID:
523 case INT4OID:
524#if SIZEOF_ZEND_LONG >= 8
525 case INT8OID:
526#endif
528 break;
529 case FLOAT4OID:
530 case FLOAT8OID:
531 if (strncmp(ptr, "Infinity", len) == 0) {
533 } else if (strncmp(ptr, "-Infinity", len) == 0) {
535 } else if (strncmp(ptr, "NaN", len) == 0) {
537 } else {
539 }
540 break;
541
542 case OIDOID: {
543 char *end_ptr;
544 Oid oid = (Oid)strtoul(ptr, &end_ptr, 10);
545 if (type && *type == PDO_PARAM_LOB) {
546 /* If column was bound as LOB, return a stream. */
547 int loid = lo_open(S->H->server, oid, INV_READ);
548 if (loid >= 0) {
549 php_stream *stream = pdo_pgsql_create_lob_stream(&stmt->database_object_handle, loid, oid);
550 if (stream) {
551 php_stream_to_zval(stream, result);
552 return 1;
553 }
554 }
555 return 0;
556 } else {
557 /* Otherwise return OID as integer. */
558 ZVAL_LONG(result, oid);
559 }
560 break;
561 }
562
563 case BYTEAOID: {
564 size_t tmp_len;
565 char *tmp_ptr = (char *)PQunescapeBytea((unsigned char *) ptr, &tmp_len);
566 if (!tmp_ptr) {
567 /* PQunescapeBytea returned an error */
568 return 0;
569 }
570
571 zend_string *str = zend_string_init(tmp_ptr, tmp_len, 0);
573 php_stream_to_zval(stream, result);
574 zend_string_release(str);
575 PQfreemem(tmp_ptr);
576 break;
577 }
578
579 default:
581 break;
582 }
583 }
584
585 return 1;
586}
587
588static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGconn *conn)
589{
590 char *table_name = NULL;
591 PGresult *tmp_res;
592 char *querystr = NULL;
593
594 spprintf(&querystr, 0, "SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);
595
596 if ((tmp_res = PQexec(conn, querystr)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
597 if (tmp_res) {
598 PQclear(tmp_res);
599 }
600 efree(querystr);
601 return 0;
602 }
603 efree(querystr);
604
605 if (1 == PQgetisnull(tmp_res, 0, 0) || (table_name = PQgetvalue(tmp_res, 0, 0)) == NULL) {
606 PQclear(tmp_res);
607 return 0;
608 }
609
610 table_name = estrdup(table_name);
611
612 PQclear(tmp_res);
613 return table_name;
614}
615
616static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
617{
619 PGresult *res;
620 char *q=NULL;
621 ExecStatusType status;
622 Oid table_oid;
623 char *table_name=NULL;
624
625 if (!S->result) {
626 return FAILURE;
627 }
628
629 if (colno >= stmt->column_count) {
630 return FAILURE;
631 }
632
634 add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
635
636 table_oid = PQftable(S->result, colno);
637 add_assoc_long(return_value, "pgsql:table_oid", table_oid);
638 table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H->server);
639 if (table_name) {
640 add_assoc_string(return_value, "table", table_name);
641 efree(table_name);
642 }
643
644 switch (S->cols[colno].pgsql_type) {
645 case BOOLOID:
646 add_assoc_string(return_value, "native_type", BOOLLABEL);
647 break;
648 case BYTEAOID:
649 add_assoc_string(return_value, "native_type", BYTEALABEL);
650 break;
651 case INT8OID:
652 add_assoc_string(return_value, "native_type", INT8LABEL);
653 break;
654 case INT2OID:
655 add_assoc_string(return_value, "native_type", INT2LABEL);
656 break;
657 case INT4OID:
658 add_assoc_string(return_value, "native_type", INT4LABEL);
659 break;
660 case FLOAT4OID:
661 add_assoc_string(return_value, "native_type", FLOAT4LABEL);
662 break;
663 case FLOAT8OID:
664 add_assoc_string(return_value, "native_type", FLOAT8LABEL);
665 break;
666 case TEXTOID:
667 add_assoc_string(return_value, "native_type", TEXTLABEL);
668 break;
669 case VARCHAROID:
670 add_assoc_string(return_value, "native_type", VARCHARLABEL);
671 break;
672 case DATEOID:
673 add_assoc_string(return_value, "native_type", DATELABEL);
674 break;
675 case TIMESTAMPOID:
676 add_assoc_string(return_value, "native_type", TIMESTAMPLABEL);
677 break;
678 default:
679 /* Fetch metadata from Postgres system catalogue */
680 spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
681 res = PQexec(S->H->server, q);
682 efree(q);
683 status = PQresultStatus(res);
684 if (status == PGRES_TUPLES_OK && 1 == PQntuples(res)) {
685 add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0));
686 }
687 PQclear(res);
688 }
689
690 enum pdo_param_type param_type;
691 switch (S->cols[colno].pgsql_type) {
692 case BOOLOID:
693 param_type = PDO_PARAM_BOOL;
694 break;
695 case INT2OID:
696 case INT4OID:
697 case INT8OID:
698 param_type = PDO_PARAM_INT;
699 break;
700 case OIDOID:
701 case BYTEAOID:
702 param_type = PDO_PARAM_LOB;
703 break;
704 default:
705 param_type = PDO_PARAM_STR;
706 }
707 add_assoc_long(return_value, "pdo_type", param_type);
708
709 return 1;
710}
711
712static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt)
713{
714 return 1;
715}
716
717static int pgsql_stmt_get_attr(pdo_stmt_t *stmt, zend_long attr, zval *val)
718{
720
721 switch (attr) {
722#ifdef HAVE_PG_RESULT_MEMORY_SIZE
724 if(stmt->executed) {
725 ZVAL_LONG(val, PQresultMemorySize(S->result));
726 } else {
727 char *tmp;
728 spprintf(&tmp, 0, "statement '%s' has not been executed yet", S->stmt_name);
729
730 pdo_pgsql_error_stmt_msg(stmt, 0, "HY000", tmp);
731 efree(tmp);
732
733 ZVAL_NULL(val);
734 }
735 return 1;
736#endif
737
738 default:
739 (void)S;
740 return 0;
741 }
742}
743
745 pgsql_stmt_dtor,
746 pgsql_stmt_execute,
747 pgsql_stmt_fetch,
748 pgsql_stmt_describe,
749 pgsql_stmt_get_col,
750 pgsql_stmt_param_hook,
751 NULL, /* set_attr */
752 pgsql_stmt_get_attr,
753 pgsql_stmt_get_column_meta,
754 NULL, /* next_rowset */
755 pdo_pgsql_stmt_cursor_closer
756};
size_t len
Definition apprentice.c:174
char s[4]
Definition cdf.c:77
DNS_STATUS status
Definition dns_win32.c:49
zend_ffi_type * type
Definition ffi.c:3812
zend_string * res
Definition ffi.c:4692
void * ptr
Definition ffi.c:3814
new_type attr
Definition ffi.c:4364
zval * val
Definition ffi.c:4262
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
zend_long offset
#define NULL
Definition gdcache.h:45
#define S(s, l, r)
Definition hash_gost.c:121
#define H(x, y, z)
Definition md5.c:146
void pdo_pgsql_close_lob_streams(pdo_dbh_t *dbh)
const php_stream_ops pdo_pgsql_lob_stream_ops
php_stream * pdo_pgsql_create_lob_stream(zval *dbh, int lfd, Oid oid)
#define INT4LABEL
#define TIMESTAMPLABEL
#define TIMESTAMPOID
#define OIDOID
#define VARCHAROID
#define FLOAT8LABEL
#define INT8LABEL
#define INT2OID
#define FLOAT4OID
#define FLOAT4LABEL
#define TEXTOID
#define INT8OID
#define BYTEALABEL
#define FLOAT8OID
#define INT2LABEL
#define BOOLOID
#define TEXTLABEL
#define BOOLLABEL
#define BYTEAOID
#define VARCHARLABEL
#define DATEOID
#define INT4OID
#define DATELABEL
const struct pdo_stmt_methods pgsql_stmt_methods
#define php_stream_memory_open(mode, str)
#define TEMP_STREAM_READONLY
char sqlstate[6]
struct _pdo_stmt_t pdo_stmt_t
pdo_param_type
@ PDO_PARAM_LOB
@ PDO_PARAM_INPUT_OUTPUT
@ PDO_PARAM_BOOL
@ PDO_PARAM_INT
@ 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
@ PDO_FETCH_ORI_ABS
@ PDO_FETCH_ORI_LAST
@ PDO_FETCH_ORI_PRIOR
@ PDO_FETCH_ORI_FIRST
@ PDO_FETCH_ORI_REL
@ PDO_FETCH_ORI_NEXT
@ PDO_PLACEHOLDER_NAMED
#define PDO_PARAM_TYPE(x)
#define pdo_pgsql_sqlstate(r)
@ PDO_PGSQL_ATTR_RESULT_MEMORY_SIZE
#define pdo_pgsql_error_stmt(s, e, z)
#define pdo_pgsql_error_stmt_msg(stmt, e, sqlstate, msg)
struct _php_stream php_stream
Definition php_streams.h:96
#define PHP_STREAM_COPY_ALL
#define php_stream_to_zval(stream, zval)
#define php_stream_is(stream, anops)
#define php_stream_copy_to_mem(src, maxlen, persistent)
#define php_stream_from_zval_no_verify(xstr, pzval)
#define spprintf
Definition spprintf.h:29
zval database_object_handle
void * abstract
zend_ulong precision
zend_string * name
#define ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define ZVAL_STRINGL_FAST(z, s, l)
Definition zend_API.h:983
#define array_init(arg)
Definition zend_API.h:537
#define ZVAL_EMPTY_STRING(z)
Definition zend_API.h:961
#define ecalloc(nmemb, size)
Definition zend_alloc.h:158
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
struct _zval_struct zval
strlen(string $string)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
#define snprintf
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
#define EG(v)
int32_t zend_long
Definition zend_long.h:42
#define ZEND_ATOL(s)
Definition zend_long.h:101
#define ZEND_LONG_FMT
Definition zend_long.h:87
struct _zend_string zend_string
#define IS_OBJ_VALID(o)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
#define convert_to_string(op)
#define ZEND_FALLTHROUGH
#define zend_always_inline
#define ZEND_NAN
#define ZEND_INFINITY
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define P
ZEND_API double zend_strtod(const char *s00, const char **se)
#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 ZVAL_NULL(z)
#define ZVAL_LONG(z, l)
#define IS_RESOURCE
Definition zend_types.h:609
#define IS_OBJ_FREE_CALLED
Definition zend_types.h:829
#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 Z_OBJ_HANDLE(zval)
Definition zend_types.h:998
#define ZVAL_DOUBLE(z, d)
#define Z_ISREF(zval)
Definition zend_types.h:953
#define OBJ_FLAGS(obj)
Definition zend_types.h:831
#define ZVAL_BOOL(z, b)
#define Z_OBJ(zval)
Definition zend_types.h:989
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval * return_value
bool result