30#ifdef HAVE_NETINET_IN_H
31#include <netinet/in.h>
35#define BOOLLABEL "bool"
37#define BYTEALABEL "bytea"
39#define DATELABEL "date"
41#define INT2LABEL "int2"
43#define INT4LABEL "int4"
45#define INT8LABEL "int8"
48#define TEXTLABEL "text"
50#define TIMESTAMPLABEL "timestamp"
51#define TIMESTAMPOID 1114
52#define VARCHARLABEL "varchar"
53#define VARCHAROID 1043
54#define FLOAT4LABEL "float4"
56#define FLOAT8LABEL "float8"
75 if (
S->is_prepared && server_obj_usable) {
78#ifndef HAVE_PQCLOSEPREPARED
82 spprintf(&q, 0,
"DEALLOCATE %s",
S->stmt_name);
83 res = PQexec(
H->server, q);
86 res = PQclosePrepared(
H->server,
S->stmt_name);
95 if (
S->param_lengths) {
97 S->param_lengths =
NULL;
99 if (
S->param_values) {
101 S->param_values =
NULL;
103 if (
S->param_formats) {
105 S->param_formats =
NULL;
107 if (
S->param_types) {
109 S->param_types =
NULL;
112 zend_string_release(
S->query);
116 if (
S->cursor_name) {
117 if (server_obj_usable) {
122 spprintf(&q, 0,
"CLOSE %s",
S->cursor_name);
123 res = PQexec(
H->server, q);
128 S->cursor_name =
NULL;
140static int pgsql_stmt_execute(
pdo_stmt_t *stmt)
146 bool in_trans = stmt->dbh->methods->in_transaction(stmt->dbh);
156 if (
S->cursor_name) {
159 if (
S->is_prepared) {
160 spprintf(&q, 0,
"CLOSE %s",
S->cursor_name);
161 PQclear(PQexec(
H->server, q));
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);
170 status = PQresultStatus(
S->result);
171 if (
status != PGRES_COMMAND_OK &&
status != PGRES_TUPLES_OK) {
181 spprintf(&q, 0,
"FETCH FORWARD 0 FROM %s",
S->cursor_name);
182 S->result = PQexec(
H->server, q);
184 }
else if (
S->stmt_name) {
187 if (!
S->is_prepared) {
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,
194 status = PQresultStatus(
S->result);
196 case PGRES_COMMAND_OK:
197 case PGRES_TUPLES_OK:
212#ifndef HAVE_PQCLOSEPREPARED
217 res = PQclosePrepared(
H->server,
S->stmt_name);
230 S->result = PQexecPrepared(
H->server,
S->stmt_name,
232 zend_hash_num_elements(stmt->bound_params) :
234 (
const char**)
S->param_values,
240 S->result = PQexecParams(
H->server,
ZSTR_VAL(
S->query),
241 stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
243 (
const char**)
S->param_values,
249 S->result = PQexec(
H->server,
ZSTR_VAL(stmt->active_query_string));
251 status = PQresultStatus(
S->result);
253 if (
status != PGRES_COMMAND_OK &&
status != PGRES_TUPLES_OK) {
258 stmt->column_count = (int) PQnfields(
S->result);
259 if (
S->cols ==
NULL) {
263 if (
status == PGRES_COMMAND_OK) {
264 stmt->row_count =
ZEND_ATOL(PQcmdTuples(
S->result));
265 H->pgoid = PQoidValue(
S->result);
267 stmt->row_count = (
zend_long)PQntuples(
S->result);
270 if (in_trans && !stmt->dbh->methods->in_transaction(stmt->dbh)) {
283 switch (event_type) {
285 if (param->driver_data) {
286 efree(param->driver_data);
293 if (
ZSTR_VAL(param->name)[0] ==
'$') {
299 if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map,
300 param->name)) !=
NULL) {
312 if (!stmt->bound_param_map) {
315 if (!zend_hash_index_exists(stmt->bound_param_map, param->paramno)) {
327 if (!stmt->bound_param_map) {
330 if (!
S->param_values) {
332 zend_hash_num_elements(stmt->bound_param_map),
335 zend_hash_num_elements(stmt->bound_param_map),
338 zend_hash_num_elements(stmt->bound_param_map),
341 zend_hash_num_elements(stmt->bound_param_map),
344 if (param->paramno >= 0) {
354 if (
Z_ISREF(param->parameter)) {
355 parameter =
Z_REFVAL(param->parameter);
357 parameter = ¶m->parameter;
371 param->driver_data =
P;
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;
396 S->param_values[param->paramno] =
NULL;
397 S->param_lengths[param->paramno] = 0;
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;
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;
410 S->param_types[param->paramno] = 0;
411 S->param_formats[param->paramno] = 1;
413 S->param_types[param->paramno] = 0;
436 if (
S->cursor_name) {
437 char *ori_str =
NULL;
457 spprintf(&q, 0,
"FETCH %s FROM %s", ori_str,
S->cursor_name);
459 S->result = PQexec(
S->H->server, q);
461 status = PQresultStatus(
S->result);
463 if (
status != PGRES_COMMAND_OK &&
status != PGRES_TUPLES_OK) {
468 if (PQntuples(
S->result)) {
475 if (
S->current_row < stmt->row_count) {
484static int pgsql_stmt_describe(
pdo_stmt_t *stmt,
int colno)
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);
511 if (PQgetisnull(
S->result,
S->current_row - 1, colno)) {
514 char *
ptr = PQgetvalue(
S->result,
S->current_row - 1, colno);
515 size_t len = PQgetlength(
S->result,
S->current_row - 1, colno);
517 switch (
S->cols[colno].pgsql_type) {
524#if SIZEOF_ZEND_LONG >= 8
544 Oid oid = (Oid)strtoul(
ptr, &end_ptr, 10);
547 int loid = lo_open(
S->H->server, oid, INV_READ);
565 char *tmp_ptr = (
char *)PQunescapeBytea((
unsigned char *)
ptr, &tmp_len);
571 zend_string *str = zend_string_init(tmp_ptr, tmp_len, 0);
574 zend_string_release(str);
588static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGconn *conn)
590 char *table_name =
NULL;
592 char *querystr =
NULL;
594 spprintf(&querystr, 0,
"SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);
596 if ((tmp_res = PQexec(conn, querystr)) ==
NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
605 if (1 == PQgetisnull(tmp_res, 0, 0) || (table_name = PQgetvalue(tmp_res, 0, 0)) ==
NULL) {
610 table_name =
estrdup(table_name);
623 char *table_name=
NULL;
629 if (colno >= stmt->column_count) {
634 add_assoc_long(
return_value,
"pgsql:oid",
S->cols[colno].pgsql_type);
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);
644 switch (
S->cols[colno].pgsql_type) {
680 spprintf(&q, 0,
"SELECT TYPNAME FROM PG_TYPE WHERE OID=%u",
S->cols[colno].pgsql_type);
681 res = PQexec(
S->H->server, q);
684 if (
status == PGRES_TUPLES_OK && 1 == PQntuples(
res)) {
691 switch (
S->cols[colno].pgsql_type) {
712static int pdo_pgsql_stmt_cursor_closer(
pdo_stmt_t *stmt)
722#ifdef HAVE_PG_RESULT_MEMORY_SIZE
728 spprintf(&tmp, 0,
"statement '%s' has not been executed yet",
S->stmt_name);
750 pgsql_stmt_param_hook,
753 pgsql_stmt_get_column_meta,
755 pdo_pgsql_stmt_cursor_closer
zend_ffi_ctype_name_buf buf
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)
const struct pdo_stmt_methods pgsql_stmt_methods
#define php_stream_memory_open(mode, str)
#define TEMP_STREAM_READONLY
struct _pdo_stmt_t pdo_stmt_t
@ PDO_PARAM_EVT_FETCH_POST
@ PDO_PARAM_EVT_NORMALIZE
@ PDO_PARAM_EVT_FETCH_PRE
@ PDO_PARAM_EVT_EXEC_POST
#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
#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)
zval database_object_handle
#define ZVAL_STRINGL(z, s, l)
#define ZVAL_STRINGL_FAST(z, s, l)
#define ZVAL_EMPTY_STRING(z)
#define ecalloc(nmemb, size)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
struct _zend_string zend_string
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
#define convert_to_string(op)
#define zend_always_inline
ZEND_API double zend_strtod(const char *s00, const char **se)
#define Z_STRVAL_P(zval_p)
#define IS_OBJ_FREE_CALLED
#define Z_STRLEN_P(zval_p)
#define Z_OBJ_HANDLE(zval)
#define ZVAL_DOUBLE(z, d)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)