summaryrefslogtreecommitdiff
path: root/ext/pdo_pgsql
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_pgsql')
-rw-r--r--ext/pdo_pgsql/config.m420
-rw-r--r--ext/pdo_pgsql/config.w325
-rw-r--r--ext/pdo_pgsql/pdo_pgsql.c1
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c68
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c86
-rw-r--r--ext/pdo_pgsql/php_pdo_pgsql_int.h13
-rw-r--r--ext/pdo_pgsql/tests/bug48764.phpt22
-rw-r--r--ext/pdo_pgsql/tests/bug62479.phpt4
-rw-r--r--ext/pdo_pgsql/tests/bug_33876.phpt2
-rw-r--r--ext/pdo_pgsql/tests/disable_prepares.phpt54
10 files changed, 166 insertions, 109 deletions
diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4
index afe42e06a5..c61c5de4f4 100644
--- a/ext/pdo_pgsql/config.m4
+++ b/ext/pdo_pgsql/config.m4
@@ -34,7 +34,7 @@ if test "$PHP_PDO_PGSQL" != "no"; then
else
PGSQL_SEARCH_PATHS=$PHP_PDO_PGSQL
fi
-
+
for i in $PGSQL_SEARCH_PATHS; do
for j in include include/pgsql include/postgres include/postgresql ""; do
if test -r "$i/$j/libpq-fe.h"; then
@@ -47,7 +47,7 @@ if test "$PHP_PDO_PGSQL" != "no"; then
done
for j in $PHP_LIBDIR $PHP_LIBDIR/pgsql $PHP_LIBDIR/postgres $PHP_LIBDIR/postgresql ""; do
- if test -f "$i/$j/libpq.so" || test -f "$i/$j/libpq.a"; then
+ if test -f "$i/$j/libpq.so" || test -f "$i/$j/libpq.a"; then
PGSQL_LIBDIR=$i/$j
fi
done
@@ -84,17 +84,11 @@ if test "$PHP_PDO_PGSQL" != "no"; then
old_LIBS=$LIBS
old_LDFLAGS=$LDFLAGS
LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS"
- AC_CHECK_LIB(pq, PQparameterStatus,AC_DEFINE(HAVE_PQPARAMETERSTATUS,1,[PostgreSQL 7.4 or later]), [
- echo "Unable to build the PDO PostgreSQL driver: libpq 7.4+ is required"
- exit 1
- ])
-
- AC_CHECK_LIB(pq, PQprepare,AC_DEFINE(HAVE_PQPREPARE,1,[PostgreSQL 8.0 or later]))
- AC_CHECK_LIB(pq, PQescapeStringConn, AC_DEFINE(HAVE_PQESCAPE_CONN,1,[PostgreSQL 8.1.4 or later]))
- AC_CHECK_LIB(pq, PQescapeByteaConn, AC_DEFINE(HAVE_PQESCAPE_BYTEA_CONN,1,[PostgreSQL 8.1.4 or later]))
- AC_CHECK_LIB(pq, pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether libpq is compiled with --enable-multibyte]))
-
+ AC_CHECK_LIB(pq, PQprepare,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
+ AC_CHECK_LIB(pq, PQexecParams,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
+ AC_CHECK_LIB(pq, PQescapeStringConn,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
+ AC_CHECK_LIB(pq, PQescapeByteaConn,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required]))
LIBS=$old_LIBS
LDFLAGS=$old_LDFLAGS
@@ -124,6 +118,6 @@ if test "$PHP_PDO_PGSQL" != "no"; then
PHP_NEW_EXTENSION(pdo_pgsql, pdo_pgsql.c pgsql_driver.c pgsql_statement.c, $ext_shared,,-I$pdo_cv_inc_path $PDO_PGSQL_CFLAGS)
ifdef([PHP_ADD_EXTENSION_DEP],
[
- PHP_ADD_EXTENSION_DEP(pdo_pgsql, pdo)
+ PHP_ADD_EXTENSION_DEP(pdo_pgsql, pdo)
])
fi
diff --git a/ext/pdo_pgsql/config.w32 b/ext/pdo_pgsql/config.w32
index 223780e3f9..2097dc2da9 100644
--- a/ext/pdo_pgsql/config.w32
+++ b/ext/pdo_pgsql/config.w32
@@ -13,10 +13,7 @@ if (PHP_PDO_PGSQL != "no") {
}
AC_DEFINE('HAVE_PDO_PGSQL', 1, 'Have PostgreSQL library');
- AC_DEFINE('HAVE_PQESCAPE_BYTEA_CONN', 1, 'Have PQescapeByteaConn');
- AC_DEFINE('HAVE_PQESCAPE_CONN', 1, 'Have PQescapeConn');
- AC_DEFINE('HAVE_PQPREPARE', 1, 'Have PQprepare');
- ADD_FLAG('CFLAGS_PDO_PGSQL', "/D HAVE_PQPARAMETERSTATUS=1 /D HAVE_PQPROTOCOLVERSION=1 /D HAVE_PGTRANSACTIONSTATUS=1 /D HAVE_PQUNESCAPEBYTEA=1 /D HAVE_PQRESULTERRORFIELD=1 /D HAVE_PQESCAPE_CONN=1 /D HAVE_PQESCAPE_BYTEA_CONN=1");
+
ADD_EXTENSION_DEP('pdo_pgsql', 'pdo');
} else {
WARNING("pdo_pgsql not enabled; libraries and headers not found");
diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c
index 8e4cc97fb5..fe003f8ab9 100644
--- a/ext/pdo_pgsql/pdo_pgsql.c
+++ b/ext/pdo_pgsql/pdo_pgsql.c
@@ -86,6 +86,7 @@ ZEND_GET_MODULE(pdo_pgsql)
PHP_MINIT_FUNCTION(pdo_pgsql)
{
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT", PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT);
+ REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_PREPARES", PDO_PGSQL_ATTR_DISABLE_PREPARES);
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_IDLE", (long)PGSQL_TRANSACTION_IDLE);
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_ACTIVE", (long)PGSQL_TRANSACTION_ACTIVE);
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INTRANS", (long)PGSQL_TRANSACTION_INTRANS);
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index ebdaaed3f1..24a5865c75 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -58,7 +58,7 @@ static char * _pdo_pgsql_trim_message(const char *message, int persistent)
tmp = pemalloc(i + 1, persistent);
memcpy(tmp, message, i);
tmp[i] = '\0';
-
+
return tmp;
}
@@ -220,12 +220,11 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt));
int scrollable;
-#if HAVE_PQPREPARE
int ret;
char *nsql = NULL;
int nsql_len = 0;
int emulate = 0;
-#endif
+ int execute_only = 0;
S->H = H;
stmt->driver_data = S;
@@ -239,19 +238,21 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
efree(S->cursor_name);
}
spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter);
-#if HAVE_PQPREPARE
emulate = 1;
-#endif
- }
-
-#if HAVE_PQPREPARE
- else if (driver_options) {
- if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, H->disable_native_prepares TSRMLS_CC) == 1 ||
- pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, H->emulate_prepares TSRMLS_CC) == 1) {
+ } else if (driver_options) {
+ if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, H->disable_native_prepares TSRMLS_CC) == 1) {
+ php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead");
+ emulate = 1;
+ }
+ if (pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, H->emulate_prepares TSRMLS_CC) == 1) {
emulate = 1;
}
+ if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_PREPARES, H->disable_prepares TSRMLS_CC) == 1) {
+ execute_only = 1;
+ }
} else {
emulate = H->disable_native_prepares || H->emulate_prepares;
+ execute_only = H->disable_prepares;
}
if (!emulate && PQprotocolVersion(H->server) > 2) {
@@ -268,9 +269,12 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
return 0;
}
- spprintf(&S->stmt_name, 0, "pdo_stmt_%08x", ++H->stmt_counter);
- /* that's all for now; we'll defer the actual prepare until the first execute call */
-
+ if (!execute_only) {
+ /* prepared query: set the query name and defer the
+ actual prepare until the first execute call */
+ spprintf(&S->stmt_name, 0, "pdo_stmt_%08x", ++H->stmt_counter);
+ }
+
if (nsql) {
S->query = nsql;
} else {
@@ -279,7 +283,6 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
return 1;
}
-#endif
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
return 1;
@@ -291,7 +294,7 @@ static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRM
PGresult *res;
long ret = 1;
ExecStatusType qs;
-
+
if (!(res = PQexec(H->server, sql))) {
/* fatal error */
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
@@ -315,15 +318,11 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
unsigned char *escaped;
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
size_t tmp_len;
-
+
switch (paramtype) {
case PDO_PARAM_LOB:
/* escapedlen returned by PQescapeBytea() accounts for trailing 0 */
-#ifdef HAVE_PQESCAPE_BYTEA_CONN
escaped = PQescapeByteaConn(H->server, (unsigned char *)unquoted, (size_t)unquotedlen, &tmp_len);
-#else
- escaped = PQescapeBytea((unsigned char *)unquoted, (size_t)unquotedlen, &tmp_len);
-#endif
*quotedlen = (int)tmp_len + 1;
*quoted = emalloc(*quotedlen + 1);
memcpy((*quoted)+1, escaped, *quotedlen-2);
@@ -335,11 +334,7 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
default:
*quoted = safe_emalloc(2, unquotedlen, 3);
(*quoted)[0] = '\'';
-#ifndef HAVE_PQESCAPE_CONN
- *quotedlen = PQescapeString(*quoted + 1, unquoted, (size_t)unquotedlen);
-#else
*quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, (size_t)unquotedlen, NULL);
-#endif
(*quoted)[*quotedlen + 1] = '\'';
(*quoted)[*quotedlen + 2] = '\0';
*quotedlen += 2;
@@ -441,8 +436,8 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value
case PDO_ATTR_SERVER_INFO: {
int spid = PQbackendPID(H->server);
char *tmp;
- spprintf(&tmp, 0,
- "PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
+ spprintf(&tmp, 0,
+ "PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
spid,
(char*)PQparameterStatus(H->server, "client_encoding"),
(char*)PQparameterStatus(H->server, "is_superuser"),
@@ -453,7 +448,7 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value
break;
default:
- return 0;
+ return 0;
}
return 1;
@@ -577,7 +572,7 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray)
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) {
int query_len;
convert_to_string_ex(tmp);
-
+
if (buffer_len < Z_STRLEN_PP(tmp)) {
buffer_len = Z_STRLEN_PP(tmp);
query = erealloc(query, buffer_len + 2); /* room for \n\0 */
@@ -873,7 +868,7 @@ static PHP_METHOD(PDO, pgsqlCopyToArray)
int ret = PQgetCopyData(H->server, &csv, 0);
if (ret == -1) {
break; /* copy done */
- } else if (ret > 0) {
+ } else if (ret > 0) {
add_next_index_stringl(return_value, csv, ret);
PQfreemem(csv);
} else {
@@ -951,7 +946,7 @@ static PHP_METHOD(PDO, pgsqlLOBOpen)
if (strpbrk(modestr, "+w")) {
mode = INV_READ|INV_WRITE;
}
-
+
dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
PDO_CONSTRUCT_CHECK;
PDO_DBH_CLEAR_ERR();
@@ -1118,15 +1113,16 @@ static int pdo_pgsql_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
switch (attr) {
-#if HAVE_PQPREPARE
case PDO_ATTR_EMULATE_PREPARES:
H->emulate_prepares = Z_LVAL_P(val);
return 1;
case PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT:
+ php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead");
H->disable_native_prepares = Z_LVAL_P(val);
return 1;
-#endif
-
+ case PDO_PGSQL_ATTR_DISABLE_PREPARES:
+ H->disable_prepares = Z_LVAL_P(val);
+ return 1;
default:
return 0;
}
@@ -1163,7 +1159,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
H->einfo.errcode = 0;
H->einfo.errmsg = NULL;
-
+
/* PostgreSQL wants params in the connect string to be separated by spaces,
* if the PDO standard semicolons are used, we convert them to spaces
*/
@@ -1233,7 +1229,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
dbh->max_escaped_char_length = 2;
ret = 1;
-
+
cleanup:
dbh->methods = &pgsql_methods;
if (!ret) {
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index 904bce6c67..c9c9e5c450 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -54,7 +54,6 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
S->result = NULL;
}
-#if HAVE_PQPREPARE
if (S->stmt_name) {
pdo_pgsql_db_handle *H = S->H;
char *q = NULL;
@@ -91,7 +90,6 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
efree(S->query);
S->query = NULL;
}
-#endif
if (S->cursor_name) {
pdo_pgsql_db_handle *H = S->H;
@@ -105,7 +103,7 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
efree(S->cursor_name);
S->cursor_name = NULL;
}
-
+
if(S->cols) {
efree(S->cols);
S->cols = NULL;
@@ -126,7 +124,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
PQclear(S->result);
S->result = NULL;
}
-
+
S->current_row = 0;
if (S->cursor_name) {
@@ -156,16 +154,14 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name);
S->result = PQexec(H->server, q);
efree(q);
- } else
-#if HAVE_PQPREPARE
- if (S->stmt_name) {
+ } else if (S->stmt_name) {
/* using a prepared statement */
if (!S->is_prepared) {
stmt_retry:
/* we deferred the prepare until now, because we didn't
* know anything about the parameter types; now we do */
- S->result = PQprepare(H->server, S->stmt_name, S->query,
+ S->result = PQprepare(H->server, S->stmt_name, S->query,
stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
S->param_types);
status = PQresultStatus(S->result);
@@ -178,10 +174,10 @@ stmt_retry:
break;
default: {
char *sqlstate = pdo_pgsql_sqlstate(S->result);
- /* 42P05 means that the prepared statement already existed. this can happen if you use
- * a connection pooling software line pgpool which doesn't close the db-connection once
- * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
- * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
+ /* 42P05 means that the prepared statement already existed. this can happen if you use
+ * a connection pooling software line pgpool which doesn't close the db-connection once
+ * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
+ * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
* deallocate it and retry ONCE (thies 2005.12.15)
*/
if (sqlstate && !strcmp(sqlstate, "42P05")) {
@@ -208,9 +204,17 @@ stmt_retry:
S->param_lengths,
S->param_formats,
0);
- } else
-#endif
- {
+ } else if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED) {
+ /* execute query with parameters */
+ S->result = PQexecParams(H->server, S->query,
+ stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
+ S->param_types,
+ (const char**)S->param_values,
+ S->param_lengths,
+ S->param_formats,
+ 0);
+ } else {
+ /* execute plain query (with embedded parameters) */
S->result = PQexec(H->server, stmt->active_query_string);
}
status = PQresultStatus(S->result);
@@ -238,10 +242,9 @@ stmt_retry:
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
enum pdo_param_event event_type TSRMLS_DC)
{
-#if HAVE_PQPREPARE
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
- if (S->stmt_name && param->is_param) {
+ if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED && param->is_param) {
switch (event_type) {
case PDO_PARAM_EVT_FREE:
if (param->driver_data) {
@@ -320,10 +323,10 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
return 1;
} else {
int len;
-
+
SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
Z_TYPE_P(param->parameter) = IS_STRING;
-
+
if ((len = php_stream_copy_to_mem(stm, &Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0)) > 0) {
Z_STRLEN_P(param->parameter) = len;
} else {
@@ -362,20 +365,15 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
}
break;
}
- } else {
-#endif
- if (param->is_param) {
- /* We need to manually convert to a pg native boolean value */
- if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
- ((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
- SEPARATE_ZVAL(&param->parameter);
- param->param_type = PDO_PARAM_STR;
- ZVAL_STRINGL(param->parameter, Z_BVAL_P(param->parameter) ? "t" : "f", 1, 1);
- }
- }
-#if HAVE_PQPREPARE
+ } else if (param->is_param) {
+ /* We need to manually convert to a pg native boolean value */
+ if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
+ ((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
+ SEPARATE_ZVAL(&param->parameter);
+ param->param_type = PDO_PARAM_STR;
+ ZVAL_STRINGL(param->parameter, Z_BVAL_P(param->parameter) ? "t" : "f", 1, 1);
+ }
}
-#endif
return 1;
}
@@ -399,7 +397,7 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
default:
return 0;
}
-
+
spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name);
efree(ori_str);
S->result = PQexec(S->H->server, q);
@@ -432,7 +430,7 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
struct pdo_column_data *cols = stmt->columns;
struct pdo_bound_param_data *param;
-
+
if (!S->result) {
return 0;
}
@@ -442,13 +440,13 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
cols[colno].maxlen = PQfsize(S->result, colno);
cols[colno].precision = PQfmod(S->result, colno);
S->cols[colno].pgsql_type = PQftype(S->result, colno);
-
+
switch(S->cols[colno].pgsql_type) {
case BOOLOID:
cols[colno].param_type = PDO_PARAM_BOOL;
break;
-
+
case OIDOID:
/* did the user bind the column as a LOB ? */
if (stmt->bound_columns && (
@@ -506,7 +504,7 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
} else {
*ptr = PQgetvalue(S->result, S->current_row - 1, colno);
*len = PQgetlength(S->result, S->current_row - 1, colno);
-
+
switch(cols[colno].param_type) {
case PDO_PARAM_INT:
@@ -520,7 +518,7 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
*ptr = (char *) &(S->cols[colno].boolval);
*len = sizeof(zend_bool);
break;
-
+
case PDO_PARAM_LOB:
if (S->cols[colno].pgsql_type == OIDOID) {
/* ooo, a real large object */
@@ -574,15 +572,15 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return
PGresult *res;
char *q=NULL;
ExecStatusType status;
-
+
if (!S->result) {
return FAILURE;
}
-
+
if (colno >= stmt->column_count) {
return FAILURE;
}
-
+
array_init(return_value);
add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
@@ -590,9 +588,9 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return
spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
res = PQexec(S->H->server, q);
efree(q);
-
+
status = PQresultStatus(res);
-
+
if (status != PGRES_TUPLES_OK) {
/* Failed to get system catalogue, but return success
* with the data we have collected so far
@@ -607,7 +605,7 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return
add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0));
done:
- PQclear(res);
+ PQclear(res);
return 1;
}
diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h
index 908f47d57c..1fedababd2 100644
--- a/ext/pdo_pgsql/php_pdo_pgsql_int.h
+++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h
@@ -43,14 +43,12 @@ typedef struct {
unsigned _reserved:31;
pdo_pgsql_error_info einfo;
Oid pgoid;
-#if HAVE_PQPREPARE
/* The following two variables have the same purpose. Unfortunately we need
- to keep track of two different attributes having the same effect.
- It might be worth to deprecate the driver specific one soon. */
+ to keep track of two different attributes having the same effect. */
int emulate_prepares;
- int disable_native_prepares;
-#endif
- unsigned int stmt_counter;
+ int disable_native_prepares; /* deprecated since 5.6 */
+ int disable_prepares;
+ unsigned int stmt_counter;
} pdo_pgsql_db_handle;
typedef struct {
@@ -66,14 +64,12 @@ typedef struct {
int current_row;
pdo_pgsql_column *cols;
char *cursor_name;
-#if HAVE_PQPREPARE
char *stmt_name;
char *query;
char **param_values;
int *param_lengths;
int *param_formats;
Oid *param_types;
-#endif
zend_bool is_prepared;
} pdo_pgsql_stmt;
@@ -95,6 +91,7 @@ extern struct pdo_stmt_methods pgsql_stmt_methods;
enum {
PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT = PDO_ATTR_DRIVER_SPECIFIC,
+ PDO_PGSQL_ATTR_DISABLE_PREPARES,
};
struct pdo_pgsql_lob_self {
diff --git a/ext/pdo_pgsql/tests/bug48764.phpt b/ext/pdo_pgsql/tests/bug48764.phpt
index 67e8f3971f..83fa5655d8 100644
--- a/ext/pdo_pgsql/tests/bug48764.phpt
+++ b/ext/pdo_pgsql/tests/bug48764.phpt
@@ -104,7 +104,7 @@ function bug($db, $options = array()) {
}
}
---EXPECT--
+--EXPECTF--
Test 1
42P18
Test 2
@@ -112,23 +112,43 @@ Test 2
OK
Test 3
42P18
+
+Deprecated: PDO::prepare(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
OK
Test 4
OK
42P18
Test 5
+
+Deprecated: PDO::setAttribute(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
+
+Deprecated: PDO::prepare(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
OK
+
+Deprecated: PDO::setAttribute(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
42P18
Test 6
OK
42P18
OK
+
+Deprecated: PDO::__construct(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
Test 7
+
+Deprecated: PDO::prepare(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
OK
+
+Deprecated: PDO::prepare(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
OK
42P18
+
+Deprecated: PDO::__construct(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
Test 8
+
+Deprecated: PDO::prepare(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
OK
+
+Deprecated: PDO::prepare(): PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead in %s on line %d
OK
OK
42P18
diff --git a/ext/pdo_pgsql/tests/bug62479.phpt b/ext/pdo_pgsql/tests/bug62479.phpt
index 2e19f15002..a12bb8d1ff 100644
--- a/ext/pdo_pgsql/tests/bug62479.phpt
+++ b/ext/pdo_pgsql/tests/bug62479.phpt
@@ -30,7 +30,7 @@ $testQuery = 'SELECT 1 as verification';
// Create temp user with space in password
$sql = sprintf($template, 'my password');
$pdo->query($sql);
-$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my password");
+$testConn = new PDO($conf['ENV']['PDOTEST_DSN'], $user, "my password");
$result = $testConn->query($testQuery)->fetch();
$check = $result[0];
var_dump($check);
@@ -42,7 +42,7 @@ $pdo->query($dropUser);
$sql = sprintf($template, "my pass''word");
$pdo->query($sql);
-$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my pass'word");
+$testConn = new PDO($conf['ENV']['PDOTEST_DSN'], $user, "my pass'word");
$result = $testConn->query($testQuery)->fetch();
$check = $result[0];
var_dump($check);
diff --git a/ext/pdo_pgsql/tests/bug_33876.phpt b/ext/pdo_pgsql/tests/bug_33876.phpt
index 6a93905b43..15c4275d80 100644
--- a/ext/pdo_pgsql/tests/bug_33876.phpt
+++ b/ext/pdo_pgsql/tests/bug_33876.phpt
@@ -54,7 +54,7 @@ echo "EMUL\n";
$res = $db->prepare('SELECT foo from test where bar = ?', array(
- PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => true));
+ PDO::ATTR_EMULATE_PREPARES => true));
# this is the portable approach to binding a bool
$res->bindValue(1, false, PDO::PARAM_BOOL);
diff --git a/ext/pdo_pgsql/tests/disable_prepares.phpt b/ext/pdo_pgsql/tests/disable_prepares.phpt
new file mode 100644
index 0000000000..99a7695404
--- /dev/null
+++ b/ext/pdo_pgsql/tests/disable_prepares.phpt
@@ -0,0 +1,54 @@
+--TEST--
+PDO PgSQL PGSQL_ATTR_DISABLE_PREPARES
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_COLUMN);
+
+$stmt = $db->prepare("SELECT statement FROM pg_prepared_statements", array(
+ PDO::ATTR_EMULATE_PREPARES => true));
+
+$stmt2 = $db->prepare("SELECT (?)::int2");
+$stmt2->execute(array(1));
+var_dump($stmt2->fetch());
+$stmt2->execute(array(2));
+var_dump($stmt2->fetch());
+
+$stmt->execute();
+$first = $stmt->fetchAll();
+
+$stmt3 = $db->prepare("SELECT (?)::int4", array(
+ PDO::PGSQL_ATTR_DISABLE_PREPARES => true));
+$stmt3->execute(array(3));
+var_dump($stmt3->fetch());
+$stmt3->execute(array(4));
+var_dump($stmt3->fetch());
+
+$stmt->execute();
+$second = $stmt->fetchAll();
+
+var_dump($first, $second);
+
+?>
+--EXPECT--
+string(1) "1"
+string(1) "2"
+string(1) "3"
+string(1) "4"
+array(1) {
+ [0]=>
+ string(17) "SELECT ($1)::int2"
+}
+array(1) {
+ [0]=>
+ string(17) "SELECT ($1)::int2"
+}