PGSQL and POD_SQL: don't include pg_config.h

Even if that header file is available, we better consider it private,
and don't include it.  The information about whether SSL support is
enabled is now missing (`USE_(OPEN)SSL`), and it seems there is no
alternative way to get it (`PQinitSSL()` is always defined), so we
remove it from the PHP info.  Furthermore, the `PG_VERSION` and
`PG_VERSION_STR` macros are no longer available, but as of libpq 9.1
there is `PQlibVersion()` which allows us to construct `PG_VERSION` in
a most likely backwards compatible manner.  The additional information
available through `PG_VERSION_STR` is lost, though, so we define
`PGSQL_LIBPQ_VERSION_STR` basically as alias of `PGSQL_LIBPQ_VERSION`,
and deprecate it right away.

Since we are now requiring at least libpq 9.1, we can remove some
further compatibility code and additional checks.

Regarding the raised requirements: official support for PostGreSQL 9.0
ended on 2015-10-08, and even CentOS 7 already has PostGreSQL 9.2, so
this is not supposed to be too much of an issue.
This commit is contained in:
Christoph M. Becker 2020-05-25 09:00:32 +02:00
parent f3efb9e3fb
commit ce668c0ec6
11 changed files with 77 additions and 193 deletions

5
NEWS
View file

@ -96,7 +96,7 @@ PHP NEWS
. Don't ignore invalid escape sequences. (sjon) . Don't ignore invalid escape sequences. (sjon)
- PGSQL: - PGSQL:
. Bumped required libpq version to 7.4. . Bumped required libpq version to 9.1. (cmb)
- PDO: - PDO:
. Changed default PDO error mode to exceptions. (AllenJB) . Changed default PDO error mode to exceptions. (AllenJB)
@ -107,6 +107,9 @@ PHP NEWS
. Added support for setting and getting the oracle OCI 18c call timeout. . Added support for setting and getting the oracle OCI 18c call timeout.
(camporter) (camporter)
- PDO_PGSQL:
. Bumped required libpq version to 9.1. (cmb)
- phpdbg: - phpdbg:
. Fixed bug #76596 (phpdbg support for display_errors=stderr). (kabel) . Fixed bug #76596 (phpdbg support for display_errors=stderr). (kabel)
. Fixed bug #76801 (too many open files). (alekitto) . Fixed bug #76801 (too many open files). (alekitto)

View file

@ -559,6 +559,10 @@ PHP 8.0 UPGRADE NOTES
. enchant_dict_add_to_personal, use enchant_dict_add instead . enchant_dict_add_to_personal, use enchant_dict_add instead
. enchant_dict_is_in_session, use enchant_dict_is_added instead . enchant_dict_is_in_session, use enchant_dict_is_added instead
- PGSQL / PDO PGSQL:
. The constant PG_VERSION_STR has now the same value as PG_VERSION, and thus
is deprecated.
- Zip: - Zip:
. Using empty file as ZipArchive is deprecated. Libzip 1.6.0 . Using empty file as ZipArchive is deprecated. Libzip 1.6.0
do not accept empty files as valid zip archives any longer. do not accept empty files as valid zip archives any longer.
@ -680,8 +684,8 @@ PHP 8.0 UPGRADE NOTES
. When mysqlnd is not used (which is the default and recommended option), . When mysqlnd is not used (which is the default and recommended option),
the minimum supported libmysqlclient version is now 5.1. the minimum supported libmysqlclient version is now 5.1.
- PGSQL: - PGSQL / PDO PGSQL:
. The PGSQL extension now required at least libpq 7.4. . The PGSQL and PDO PGSQL extensions now require at least libpq 9.1.
======================================== ========================================
10. New Global Constants 10. New Global Constants

View file

@ -24,7 +24,6 @@ if test "$PHP_PDO_PGSQL" != "no"; then
AC_MSG_RESULT([$PG_CONFIG]) AC_MSG_RESULT([$PG_CONFIG])
PGSQL_INCLUDE=`$PG_CONFIG --includedir` PGSQL_INCLUDE=`$PG_CONFIG --includedir`
PGSQL_LIBDIR=`$PG_CONFIG --libdir` PGSQL_LIBDIR=`$PG_CONFIG --libdir`
AC_DEFINE(HAVE_PG_CONFIG_H,1,[Whether to have pg_config.h])
else else
AC_MSG_RESULT(not found) AC_MSG_RESULT(not found)
if test "$PHP_PDO_PGSQL" = "yes"; then if test "$PHP_PDO_PGSQL" = "yes"; then
@ -38,9 +37,6 @@ if test "$PHP_PDO_PGSQL" != "no"; then
if test -r "$i/$j/libpq-fe.h"; then if test -r "$i/$j/libpq-fe.h"; then
PGSQL_INC_BASE=$i PGSQL_INC_BASE=$i
PGSQL_INCLUDE=$i/$j PGSQL_INCLUDE=$i/$j
if test -r "$i/$j/pg_config.h"; then
AC_DEFINE(HAVE_PG_CONFIG_H,1,[Whether to have pg_config.h])
fi
fi fi
done done
@ -70,10 +66,7 @@ if test "$PHP_PDO_PGSQL" != "no"; then
old_LDFLAGS=$LDFLAGS old_LDFLAGS=$LDFLAGS
LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS" LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS"
AC_CHECK_LIB(pq, PQprepare,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: a newer libpq is required])) AC_CHECK_LIB(pq, PQlibVersion,, AC_MSG_ERROR([Unable to build the PDO PostgreSQL driver: at least libpq 9.1 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 LIBS=$old_LIBS
LDFLAGS=$old_LDFLAGS LDFLAGS=$old_LDFLAGS

View file

@ -7,9 +7,6 @@ if (PHP_PDO_PGSQL != "no") {
CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) { CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) {
EXTENSION("pdo_pgsql", "pdo_pgsql.c pgsql_driver.c pgsql_statement.c"); EXTENSION("pdo_pgsql", "pdo_pgsql.c pgsql_driver.c pgsql_statement.c");
if (CHECK_HEADER_ADD_INCLUDE("pg_config.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + ";" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) {
ADD_FLAG('CFLAGS_PDO_PGSQL', "/D HAVE_PG_CONFIG_H");
}
if (X64) { if (X64) {
ADD_FLAG('CFLAGS_PDO_PGSQL', "/D HAVE_PG_LO64=1"); ADD_FLAG('CFLAGS_PDO_PGSQL', "/D HAVE_PG_LO64=1");
} }

View file

@ -26,11 +26,6 @@
#include "php_pdo_pgsql.h" #include "php_pdo_pgsql.h"
#include "php_pdo_pgsql_int.h" #include "php_pdo_pgsql_int.h"
#ifdef HAVE_PG_CONFIG_H
#undef SIZEOF_OFF_T
#include <pg_config.h>
#endif
/* {{{ pdo_pgsql_functions[] */ /* {{{ pdo_pgsql_functions[] */
static const zend_function_entry pdo_pgsql_functions[] = { static const zend_function_entry pdo_pgsql_functions[] = {
PHP_FE_END PHP_FE_END
@ -96,11 +91,12 @@ PHP_MSHUTDOWN_FUNCTION(pdo_pgsql)
*/ */
PHP_MINFO_FUNCTION(pdo_pgsql) PHP_MINFO_FUNCTION(pdo_pgsql)
{ {
char buf[16];
php_info_print_table_start(); php_info_print_table_start();
php_info_print_table_row(2, "PDO Driver for PostgreSQL", "enabled"); php_info_print_table_row(2, "PDO Driver for PostgreSQL", "enabled");
#ifdef HAVE_PG_CONFIG_H pdo_libpq_version(buf, sizeof(buf));
php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION); php_info_print_table_row(2, "PostgreSQL(libpq) Version", buf);
#endif
php_info_print_table_end(); php_info_print_table_end();
} }
/* }}} */ /* }}} */

View file

@ -30,7 +30,6 @@
#include "pdo/php_pdo_error.h" #include "pdo/php_pdo_error.h"
#include "ext/standard/file.h" #include "ext/standard/file.h"
#undef SIZEOF_OFF_T #undef SIZEOF_OFF_T
#include "pg_config.h" /* needed for PG_VERSION */
#include "php_pdo_pgsql.h" #include "php_pdo_pgsql.h"
#include "php_pdo_pgsql_int.h" #include "php_pdo_pgsql_int.h"
#include "zend_exceptions.h" #include "zend_exceptions.h"
@ -377,6 +376,20 @@ static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *
return id; return id;
} }
void pdo_libpq_version(char *buf, size_t len)
{
int version = PQlibVersion();
int major = version / 10000;
if (major >= 10) {
int minor = version % 10000;
snprintf(buf, len, "%d.%d", major, minor);
} else {
int minor = version / 100 % 100;
int revision = version % 100;
snprintf(buf, len, "%d.%d.%d", major, minor, revision);
}
}
static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value) static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
{ {
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
@ -390,9 +403,12 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_
ZVAL_BOOL(return_value, H->disable_prepares); ZVAL_BOOL(return_value, H->disable_prepares);
break; break;
case PDO_ATTR_CLIENT_VERSION: case PDO_ATTR_CLIENT_VERSION: {
ZVAL_STRING(return_value, PG_VERSION); char buf[16];
pdo_libpq_version(buf, sizeof(buf));
ZVAL_STRING(return_value, buf);
break; break;
}
case PDO_ATTR_SERVER_VERSION: case PDO_ATTR_SERVER_VERSION:
if (PQprotocolVersion(H->server) >= 3) { /* PostgreSQL 7.4 or later */ if (PQprotocolVersion(H->server) >= 3) { /* PostgreSQL 7.4 or later */
@ -458,8 +474,8 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_
(char*)PQparameterStatus(H->server, "DateStyle")); (char*)PQparameterStatus(H->server, "DateStyle"));
ZVAL_STR(return_value, str_info); ZVAL_STR(return_value, str_info);
}
break; break;
}
default: default:
return 0; return 0;

View file

@ -107,4 +107,6 @@ enum pdo_pgsql_specific_constants {
php_stream *pdo_pgsql_create_lob_stream(zval *pdh, int lfd, Oid oid); php_stream *pdo_pgsql_create_lob_stream(zval *pdh, int lfd, Oid oid);
extern const php_stream_ops pdo_pgsql_lob_stream_ops; extern const php_stream_ops pdo_pgsql_lob_stream_ops;
void pdo_libpq_version(char *buf, size_t len);
#endif /* PHP_PDO_PGSQL_INT_H */ #endif /* PHP_PDO_PGSQL_INT_H */

View file

@ -22,9 +22,6 @@ if test "$PHP_PGSQL" != "no"; then
AC_MSG_RESULT([$PG_CONFIG]) AC_MSG_RESULT([$PG_CONFIG])
PGSQL_INCLUDE=`$PG_CONFIG --includedir` PGSQL_INCLUDE=`$PG_CONFIG --includedir`
PGSQL_LIBDIR=`$PG_CONFIG --libdir` PGSQL_LIBDIR=`$PG_CONFIG --libdir`
if test -r "$PGSQL_INCLUDE/pg_config.h"; then
AC_DEFINE(HAVE_PG_CONFIG_H,1,[Whether to have pg_config.h])
fi
else else
AC_MSG_RESULT(not found) AC_MSG_RESULT(not found)
if test "$PHP_PGSQL" = "yes"; then if test "$PHP_PGSQL" = "yes"; then
@ -38,9 +35,6 @@ if test "$PHP_PGSQL" != "no"; then
if test -r "$i/$j/libpq-fe.h"; then if test -r "$i/$j/libpq-fe.h"; then
PGSQL_INC_BASE=$i PGSQL_INC_BASE=$i
PGSQL_INCLUDE=$i/$j PGSQL_INCLUDE=$i/$j
if test -r "$i/$j/pg_config.h"; then
AC_DEFINE(HAVE_PG_CONFIG_H,1,[Whether to have pg_config.h])
fi
fi fi
done done
@ -68,15 +62,9 @@ if test "$PHP_PGSQL" != "no"; then
old_LIBS=$LIBS old_LIBS=$LIBS
old_LDFLAGS=$LDFLAGS old_LDFLAGS=$LDFLAGS
LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS" LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS"
AC_CHECK_LIB(pq, PQprepare,, AC_MSG_ERROR([Unable to build the PostgreSQL extension: at least libpq 7.4 is required])) AC_CHECK_LIB(pq, PQlibVersion,, AC_MSG_ERROR([Unable to build the PostgreSQL extension: at least libpq 9.1 is required]))
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, pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether libpq is compiled with --enable-multibyte]))
AC_CHECK_LIB(pq, lo_create, AC_DEFINE(HAVE_PG_LO_CREATE,1,[PostgreSQL 8.1 or later]))
AC_CHECK_LIB(pq, lo_import_with_oid, AC_DEFINE(HAVE_PG_LO_IMPORT_WITH_OID,1,[PostgreSQL 8.4 or later]))
AC_CHECK_LIB(pq, lo_truncate, AC_DEFINE(HAVE_PG_LO_TRUNCATE,1,[PostgreSQL 8.3 or later]))
AC_CHECK_LIB(pq, lo_truncate64, AC_DEFINE(HAVE_PG_LO64,1,[PostgreSQL 9.3 or later])) AC_CHECK_LIB(pq, lo_truncate64, AC_DEFINE(HAVE_PG_LO64,1,[PostgreSQL 9.3 or later]))
AC_CHECK_LIB(pq, PQescapeLiteral, AC_DEFINE(HAVE_PQESCAPELITERAL,1,[PostgreSQL 9.0 or later]))
LIBS=$old_LIBS LIBS=$old_LIBS
LDFLAGS=$old_LDFLAGS LDFLAGS=$old_LDFLAGS

View file

@ -7,7 +7,7 @@ if (PHP_PGSQL != "no") {
CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) { CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) {
EXTENSION("pgsql", "pgsql.c", PHP_PGSQL_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); EXTENSION("pgsql", "pgsql.c", PHP_PGSQL_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
AC_DEFINE('HAVE_PGSQL', 1, 'Have PostgreSQL library'); AC_DEFINE('HAVE_PGSQL', 1, 'Have PostgreSQL library');
ADD_FLAG("CFLAGS_PGSQL", "/D HAVE_PG_CONFIG_H /D PGSQL_EXPORTS /D HAVE_PQESCAPE_CONN /D HAVE_PQESCAPE_BYTEA_CONN /D HAVE_PQFREEMEM /D HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT /D HAVE_PG_LO_CREATE /D HAVE_PG_LO_IMPORT_WITH_OID /D HAVE_PG_LO_TRUNCATE" + (X64 ? " /D HAVE_PG_LO64" : "") + " /D HAVE_PQESCAPELITERAL"); ADD_FLAG("CFLAGS_PGSQL", "/D PGSQL_EXPORTS /D HAVE_PQFREEMEM /D HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT" + (X64 ? " /D HAVE_PG_LO64" : "") + " ");
} else { } else {
WARNING("pgsql not enabled; libraries and headers not found"); WARNING("pgsql not enabled; libraries and headers not found");
} }

View file

@ -353,12 +353,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_tell, 0, 0, 1)
ZEND_ARG_INFO(0, large_object) ZEND_ARG_INFO(0, large_object)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
#ifdef HAVE_PG_LO_TRUNCATE
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_truncate, 0, 0, 1) ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_truncate, 0, 0, 1)
ZEND_ARG_INFO(0, large_object) ZEND_ARG_INFO(0, large_object)
ZEND_ARG_INFO(0, size) ZEND_ARG_INFO(0, size)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_error_verbosity, 0, 0, 0) ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_error_verbosity, 0, 0, 0)
ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, connection)
@ -631,9 +629,7 @@ static const zend_function_entry pgsql_functions[] = {
PHP_FE(pg_lo_export, arginfo_pg_lo_export) PHP_FE(pg_lo_export, arginfo_pg_lo_export)
PHP_FE(pg_lo_seek, arginfo_pg_lo_seek) PHP_FE(pg_lo_seek, arginfo_pg_lo_seek)
PHP_FE(pg_lo_tell, arginfo_pg_lo_tell) PHP_FE(pg_lo_tell, arginfo_pg_lo_tell)
#ifdef HAVE_PG_LO_TRUNCATE
PHP_FE(pg_lo_truncate, arginfo_pg_lo_truncate) PHP_FE(pg_lo_truncate, arginfo_pg_lo_truncate)
#endif
/* utility functions */ /* utility functions */
PHP_FE(pg_escape_string, arginfo_pg_escape_string) PHP_FE(pg_escape_string, arginfo_pg_escape_string)
PHP_FE(pg_escape_bytea, arginfo_pg_escape_bytea) PHP_FE(pg_escape_bytea, arginfo_pg_escape_bytea)
@ -715,98 +711,6 @@ static int le_link, le_plink, le_result, le_lofp, le_string;
#define pg_encoding_to_char(x) "SQL_ASCII" #define pg_encoding_to_char(x) "SQL_ASCII"
#endif #endif
#ifndef HAVE_PQESCAPE_CONN
#define PQescapeStringConn(conn, to, from, len, error) PQescapeString(to, from, len)
#endif
#ifdef HAVE_PQESCAPELITERAL
#define PGSQLescapeLiteral(conn, str, len) PQescapeLiteral(conn, str, len)
#define PGSQLescapeIdentifier(conn, str, len) PQescapeIdentifier(conn, str, len)
#define PGSQLfree(a) PQfreemem(a)
#else
#define PGSQLescapeLiteral(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 0)
#define PGSQLescapeLiteral2(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 1)
#define PGSQLescapeIdentifier(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 0, 0)
#define PGSQLfree(a) efree(a)
/* emulate libpq's PQescapeInternal() 9.0 or later */
static char *php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) /* {{{ */
{
char *result, *rp, *s;
if (!conn) {
return NULL;
}
/* allocate enough memory */
rp = result = (char *)safe_emalloc(len, 2, 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */
if (escape_literal) {
if (safe) {
size_t new_len;
char *tmp = (char *)safe_emalloc(len, 2, 1);
*rp++ = '\'';
/* PQescapeString does not escape \, but it handles multibyte chars safely.
This escape is incompatible with PQescapeLiteral. */
new_len = PQescapeStringConn(conn, tmp, str, len, NULL);
strncpy(rp, tmp, new_len);
efree(tmp);
rp += new_len;
} else {
char *encoding;
size_t tmp_len;
/* This is compatible with PQescapeLiteral, but it cannot handle multbyte chars
such as SJIS, BIG5. Raise warning and return NULL by checking
client_encoding. */
encoding = (char *) pg_encoding_to_char(PQclientEncoding(conn));
if (!strncmp(encoding, "SJIS", sizeof("SJIS")-1) ||
!strncmp(encoding, "SHIFT_JIS_2004", sizeof("SHIFT_JIS_2004")-1) ||
!strncmp(encoding, "BIG5", sizeof("BIG5")-1) ||
!strncmp(encoding, "GB18030", sizeof("GB18030")-1) ||
!strncmp(encoding, "GBK", sizeof("GBK")-1) ||
!strncmp(encoding, "JOHAB", sizeof("JOHAB")-1) ||
!strncmp(encoding, "UHC", sizeof("UHC")-1) ) {
php_error_docref(NULL, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding);
}
/* check backslashes */
tmp_len = strspn(str, "\\");
if (tmp_len != len) {
/* add " E" for escaping slashes */
*rp++ = ' ';
*rp++ = 'E';
}
*rp++ = '\'';
for (s = (char *)str; s - str < len; ++s) {
if (*s == '\'' || *s == '\\') {
*rp++ = *s;
*rp++ = *s;
} else {
*rp++ = *s;
}
}
}
*rp++ = '\'';
} else {
/* Identifier escape. */
*rp++ = '"';
for (s = (char *)str; s - str < len; ++s) {
if (*s == '"') {
*rp++ = '"';
*rp++ = '"';
} else {
*rp++ = *s;
}
}
*rp++ = '"';
}
*rp = '\0';
return result;
}
/* }}} */
#endif
/* {{{ _php_pgsql_trim_message */ /* {{{ _php_pgsql_trim_message */
static char * _php_pgsql_trim_message(const char *message, size_t *len) static char * _php_pgsql_trim_message(const char *message, size_t *len)
{ {
@ -1022,10 +926,26 @@ static PHP_GINIT_FUNCTION(pgsql)
} }
/* }}} */ /* }}} */
static void php_libpq_version(char *buf, size_t len)
{
int version = PQlibVersion();
int major = version / 10000;
if (major >= 10) {
int minor = version % 10000;
snprintf(buf, len, "%d.%d", major, minor);
} else {
int minor = version / 100 % 100;
int revision = version % 100;
snprintf(buf, len, "%d.%d.%d", major, minor, revision);
}
}
/* {{{ PHP_MINIT_FUNCTION /* {{{ PHP_MINIT_FUNCTION
*/ */
PHP_MINIT_FUNCTION(pgsql) PHP_MINIT_FUNCTION(pgsql)
{ {
char buf[16];
REGISTER_INI_ENTRIES(); REGISTER_INI_ENTRIES();
le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number); le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number);
@ -1033,11 +953,10 @@ PHP_MINIT_FUNCTION(pgsql)
le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number); le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number);
le_lofp = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql large object", module_number); le_lofp = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql large object", module_number);
le_string = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql string", module_number); le_string = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql string", module_number);
#ifdef HAVE_PG_CONFIG_H /* libpq version */
/* PG_VERSION - libpq version */ php_libpq_version(buf, sizeof(buf));
REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION", PG_VERSION, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION", buf, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", PG_VERSION_STR, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", buf, CONST_CS | CONST_PERSISTENT | CONST_DEPRECATED);
#endif
/* For connection option */ /* For connection option */
REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_CS | CONST_PERSISTENT);
@ -1184,20 +1103,13 @@ PHP_MINFO_FUNCTION(pgsql)
php_info_print_table_start(); php_info_print_table_start();
php_info_print_table_header(2, "PostgreSQL Support", "enabled"); php_info_print_table_header(2, "PostgreSQL Support", "enabled");
#ifdef HAVE_PG_CONFIG_H php_libpq_version(buf, sizeof(buf));
php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION); php_info_print_table_row(2, "PostgreSQL (libpq) Version", buf);
php_info_print_table_row(2, "PostgreSQL(libpq) ", PG_VERSION_STR);
#ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT #ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
php_info_print_table_row(2, "Multibyte character support", "enabled"); php_info_print_table_row(2, "Multibyte character support", "enabled");
#else #else
php_info_print_table_row(2, "Multibyte character support", "disabled"); php_info_print_table_row(2, "Multibyte character support", "disabled");
#endif #endif
#if defined(USE_SSL) || defined(USE_OPENSSL)
php_info_print_table_row(2, "SSL support", "enabled");
#else
php_info_print_table_row(2, "SSL support", "disabled");
#endif
#endif /* HAVE_PG_CONFIG_H */
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_persistent)); snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_persistent));
php_info_print_table_row(2, "Active Persistent Links", buf); php_info_print_table_row(2, "Active Persistent Links", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_links)); snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_links));
@ -1574,7 +1486,9 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type
break; break;
case PHP_PG_VERSION: case PHP_PG_VERSION:
array_init(return_value); array_init(return_value);
add_assoc_string(return_value, "client", PG_VERSION); char buf[16];
php_libpq_version(buf, sizeof(buf));
add_assoc_string(return_value, "client", buf);
add_assoc_long(return_value, "protocol", PQprotocolVersion(pgsql)); add_assoc_long(return_value, "protocol", PQprotocolVersion(pgsql));
if (PQprotocolVersion(pgsql) >= 3) { if (PQprotocolVersion(pgsql) >= 3) {
/* 8.0 or grater supports protorol version 3 */ /* 8.0 or grater supports protorol version 3 */
@ -3133,9 +3047,6 @@ PHP_FUNCTION(pg_lo_create)
} }
if (oid) { if (oid) {
#ifndef HAVE_PG_LO_CREATE
php_error_docref(NULL, E_NOTICE, "Passing OID value is not supported. Upgrade your PostgreSQL");
#else
switch (Z_TYPE_P(oid)) { switch (Z_TYPE_P(oid)) {
case IS_STRING: case IS_STRING:
{ {
@ -3165,7 +3076,6 @@ PHP_FUNCTION(pg_lo_create)
} }
PGSQL_RETURN_OID(pgsql_oid); PGSQL_RETURN_OID(pgsql_oid);
#endif
} }
if ((pgsql_oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == InvalidOid) { if ((pgsql_oid = lo_creat(pgsql, INV_READ|INV_WRITE)) == InvalidOid) {
@ -3544,9 +3454,6 @@ PHP_FUNCTION(pg_lo_import)
} }
if (oid) { if (oid) {
#ifndef HAVE_PG_LO_IMPORT_WITH_OID
php_error_docref(NULL, E_NOTICE, "OID value passing not supported");
#else
Oid wanted_oid; Oid wanted_oid;
switch (Z_TYPE_P(oid)) { switch (Z_TYPE_P(oid)) {
case IS_STRING: case IS_STRING:
@ -3579,7 +3486,6 @@ PHP_FUNCTION(pg_lo_import)
} }
PGSQL_RETURN_OID(returned_oid); PGSQL_RETURN_OID(returned_oid);
#endif
} }
returned_oid = lo_import(pgsql, file_in); returned_oid = lo_import(pgsql, file_in);
@ -3754,7 +3660,6 @@ PHP_FUNCTION(pg_lo_tell)
} }
/* }}} */ /* }}} */
#ifdef HAVE_PG_LO_TRUNCATE
/* {{{ proto bool pg_lo_truncate(resource large_object, int size) /* {{{ proto bool pg_lo_truncate(resource large_object, int size)
Truncate large object to size */ Truncate large object to size */
PHP_FUNCTION(pg_lo_truncate) PHP_FUNCTION(pg_lo_truncate)
@ -3789,7 +3694,6 @@ PHP_FUNCTION(pg_lo_truncate)
} }
} }
/* }}} */ /* }}} */
#endif
/* {{{ proto int pg_set_error_verbosity([resource connection,] int verbosity) /* {{{ proto int pg_set_error_verbosity([resource connection,] int verbosity)
Set error verbosity */ Set error verbosity */
@ -4162,9 +4066,7 @@ PHP_FUNCTION(pg_escape_string)
zend_string *from = NULL, *to = NULL; zend_string *from = NULL, *to = NULL;
zval *pgsql_link; zval *pgsql_link;
zend_resource *link; zend_resource *link;
#ifdef HAVE_PQESCAPE_CONN
PGconn *pgsql; PGconn *pgsql;
#endif
switch (ZEND_NUM_ARGS()) { switch (ZEND_NUM_ARGS()) {
case 1: case 1:
@ -4182,14 +4084,12 @@ PHP_FUNCTION(pg_escape_string)
} }
to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0); to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0);
#ifdef HAVE_PQESCAPE_CONN
if (link) { if (link) {
if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) {
RETURN_THROWS(); RETURN_THROWS();
} }
ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL); ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL);
} else } else
#endif
{ {
ZSTR_LEN(to) = PQescapeString(ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from)); ZSTR_LEN(to) = PQescapeString(ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from));
} }
@ -4206,9 +4106,7 @@ PHP_FUNCTION(pg_escape_bytea)
char *from = NULL, *to = NULL; char *from = NULL, *to = NULL;
size_t to_len; size_t to_len;
size_t from_len; size_t from_len;
#ifdef HAVE_PQESCAPE_BYTEA_CONN
PGconn *pgsql; PGconn *pgsql;
#endif
zval *pgsql_link; zval *pgsql_link;
zend_resource *link; zend_resource *link;
@ -4227,14 +4125,12 @@ PHP_FUNCTION(pg_escape_bytea)
break; break;
} }
#ifdef HAVE_PQESCAPE_BYTEA_CONN
if (link) { if (link) {
if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) { if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) {
RETURN_THROWS(); RETURN_THROWS();
} }
to = (char *)PQescapeByteaConn(pgsql, (unsigned char *)from, (size_t)from_len, &to_len); to = (char *)PQescapeByteaConn(pgsql, (unsigned char *)from, (size_t)from_len, &to_len);
} else } else
#endif
to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len); to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len);
RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */ RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */
@ -4301,9 +4197,9 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l
} }
if (escape_literal) { if (escape_literal) {
tmp = PGSQLescapeLiteral(pgsql, from, (size_t)from_len); tmp = PQescapeLiteral(pgsql, from, (size_t)from_len);
} else { } else {
tmp = PGSQLescapeIdentifier(pgsql, from, (size_t)from_len); tmp = PQescapeIdentifier(pgsql, from, (size_t)from_len);
} }
if (!tmp) { if (!tmp) {
php_error_docref(NULL, E_WARNING,"Failed to escape"); php_error_docref(NULL, E_WARNING,"Failed to escape");
@ -4311,7 +4207,7 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l
} }
RETVAL_STRING(tmp); RETVAL_STRING(tmp);
PGSQLfree(tmp); PQfreemem(tmp);
} }
/* }}} */ /* }}} */
@ -6052,11 +5948,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
unsigned char *tmp; unsigned char *tmp;
size_t to_len; size_t to_len;
smart_str s = {0}; smart_str s = {0};
#ifdef HAVE_PQESCAPE_BYTEA_CONN
tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val), &to_len); tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val), &to_len);
#else
tmp = PQescapeBytea(Z_STRVAL_P(val), (unsigned char *)Z_STRLEN_P(val), &to_len);
#endif
ZVAL_STRINGL(&new_val, (char *)tmp, to_len - 1); /* PQescapeBytea's to_len includes additional '\0' */ ZVAL_STRINGL(&new_val, (char *)tmp, to_len - 1); /* PQescapeBytea's to_len includes additional '\0' */
PQfreemem(tmp); PQfreemem(tmp);
php_pgsql_add_quotes(&new_val, 1); php_pgsql_add_quotes(&new_val, 1);
@ -6137,9 +6029,9 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
if (_php_pgsql_detect_identifier_escape(ZSTR_VAL(field), ZSTR_LEN(field)) == SUCCESS) { if (_php_pgsql_detect_identifier_escape(ZSTR_VAL(field), ZSTR_LEN(field)) == SUCCESS) {
zend_hash_update(Z_ARRVAL_P(result), field, &new_val); zend_hash_update(Z_ARRVAL_P(result), field, &new_val);
} else { } else {
char *escaped = PGSQLescapeIdentifier(pg_link, ZSTR_VAL(field), ZSTR_LEN(field)); char *escaped = PQescapeIdentifier(pg_link, ZSTR_VAL(field), ZSTR_LEN(field));
add_assoc_zval(result, escaped, &new_val); add_assoc_zval(result, escaped, &new_val);
PGSQLfree(escaped); PQfreemem(escaped);
} }
} }
} ZEND_HASH_FOREACH_END(); /* for */ } ZEND_HASH_FOREACH_END(); /* for */
@ -6226,9 +6118,9 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c
if (_php_pgsql_detect_identifier_escape(table, len) == SUCCESS) { if (_php_pgsql_detect_identifier_escape(table, len) == SUCCESS) {
smart_str_appendl(querystr, table, len); smart_str_appendl(querystr, table, len);
} else { } else {
char *escaped = PGSQLescapeIdentifier(pg_link, table, len); char *escaped = PQescapeIdentifier(pg_link, table, len);
smart_str_appends(querystr, escaped); smart_str_appends(querystr, escaped);
PGSQLfree(escaped); PQfreemem(escaped);
} }
if (dot) { if (dot) {
const char *after_dot = dot + 1; const char *after_dot = dot + 1;
@ -6238,10 +6130,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c
smart_str_appendc(querystr, '.'); smart_str_appendc(querystr, '.');
smart_str_appendl(querystr, after_dot, len); smart_str_appendl(querystr, after_dot, len);
} else { } else {
char *escaped = PGSQLescapeIdentifier(pg_link, after_dot, len); char *escaped = PQescapeIdentifier(pg_link, after_dot, len);
smart_str_appendc(querystr, '.'); smart_str_appendc(querystr, '.');
smart_str_appends(querystr, escaped); smart_str_appends(querystr, escaped);
PGSQLfree(escaped); PQfreemem(escaped);
} }
} }
} }
@ -6290,9 +6182,9 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
goto cleanup; goto cleanup;
} }
if (opt & PGSQL_DML_ESCAPE) { if (opt & PGSQL_DML_ESCAPE) {
tmp = PGSQLescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1); tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1);
smart_str_appends(&querystr, tmp); smart_str_appends(&querystr, tmp);
PGSQLfree(tmp); PQfreemem(tmp);
} else { } else {
smart_str_appendl(&querystr, ZSTR_VAL(fld), ZSTR_LEN(fld)); smart_str_appendl(&querystr, ZSTR_VAL(fld), ZSTR_LEN(fld));
} }
@ -6459,9 +6351,9 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
return -1; return -1;
} }
if (opt & PGSQL_DML_ESCAPE) { if (opt & PGSQL_DML_ESCAPE) {
char *tmp = PGSQLescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1); char *tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1);
smart_str_appends(querystr, tmp); smart_str_appends(querystr, tmp);
PGSQLfree(tmp); PQfreemem(tmp);
} else { } else {
smart_str_appendl(querystr, ZSTR_VAL(fld), ZSTR_LEN(fld)); smart_str_appendl(querystr, ZSTR_VAL(fld), ZSTR_LEN(fld));
} }

View file

@ -48,11 +48,6 @@ extern zend_module_entry pgsql_module_entry;
# endif # endif
#endif #endif
#ifdef HAVE_PG_CONFIG_H
#undef SIZEOF_OFF_T
#include <pg_config.h>
#endif
#ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT #ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
const char * pg_encoding_to_char(int encoding); const char * pg_encoding_to_char(int encoding);
#endif #endif
@ -141,9 +136,7 @@ PHP_FUNCTION(pg_lo_import);
PHP_FUNCTION(pg_lo_export); PHP_FUNCTION(pg_lo_export);
PHP_FUNCTION(pg_lo_seek); PHP_FUNCTION(pg_lo_seek);
PHP_FUNCTION(pg_lo_tell); PHP_FUNCTION(pg_lo_tell);
#ifdef HAVE_PG_LO_TRUNCATE
PHP_FUNCTION(pg_lo_truncate); PHP_FUNCTION(pg_lo_truncate);
#endif
/* debugging functions */ /* debugging functions */
PHP_FUNCTION(pg_trace); PHP_FUNCTION(pg_trace);