mirror of
https://github.com/php/php-src.git
synced 2025-08-18 06:58:55 +02:00
- Changed PDO_PGSQL configure script to require libpq 7.4
- Cleaned up usage of HAVE_PQ* defines - Fixed compiler warnings - Removed custom implementation of PQunescapeByte # Rationale: # - PDO_PGSQL couldn't even compile when using libpq 7.3 # - PostgreSQL 7.3 is unsupported since a long time # - Got consensus from pgsql devs on freenode
This commit is contained in:
parent
e51d4cb545
commit
c58c93b9b2
5 changed files with 29 additions and 138 deletions
|
@ -82,23 +82,18 @@ if test "$PHP_PDO_PGSQL" != "no"; then
|
|||
|
||||
old_LIBS=$LIBS
|
||||
old_LDFLAGS=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS -L$PGSQL_LIBDIR"
|
||||
AC_CHECK_LIB(pq, PQescapeString,AC_DEFINE(HAVE_PQESCAPE,1,[PostgreSQL 7.2.0 or later]))
|
||||
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, PQsetnonblocking,AC_DEFINE(HAVE_PQSETNONBLOCKING,1,[PostgreSQL 7.0.x or later]))
|
||||
AC_CHECK_LIB(pq, PQcmdTuples,AC_DEFINE(HAVE_PQCMDTUPLES,1,[Broken libpq under windows]))
|
||||
AC_CHECK_LIB(pq, PQoidValue,AC_DEFINE(HAVE_PQOIDVALUE,1,[Older PostgreSQL]))
|
||||
AC_CHECK_LIB(pq, PQclientEncoding,AC_DEFINE(HAVE_PQCLIENTENCODING,1,[PostgreSQL 7.0.x or later]))
|
||||
AC_CHECK_LIB(pq, PQparameterStatus,AC_DEFINE(HAVE_PQPARAMETERSTATUS,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQprotocolVersion,AC_DEFINE(HAVE_PQPROTOCOLVERSION,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQtransactionStatus,AC_DEFINE(HAVE_PGTRANSACTIONSTATUS,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQunescapeBytea,AC_DEFINE(HAVE_PQUNESCAPEBYTEA,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQExecParams,AC_DEFINE(HAVE_PQEXECPARAMS,1,[PostgreSQL 7.4 or later]))
|
||||
AC_CHECK_LIB(pq, PQresultErrorField,AC_DEFINE(HAVE_PQRESULTERRORFIELD,1,[PostgreSQL 7.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_DEFINE(HAVE_PQPREPARE,1,[prepared statements]))
|
||||
|
||||
LIBS=$old_LIBS
|
||||
LDFLAGS=$old_LDFLAGS
|
||||
|
|
|
@ -12,8 +12,11 @@ if (PHP_PDO_PGSQL != "no") {
|
|||
ADD_FLAG('CFLAGS_PDO_PGSQL', "/D HAVE_PG_CONFIG_H");
|
||||
}
|
||||
|
||||
AC_DEFINE('HAVE_PQPREPARE', 1, 'Have PqPrepare');
|
||||
AC_DEFINE('HAVE_PDO_PGSQL', 1, 'Have PostgreSQL library');
|
||||
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_PQEXECPARAMS', 1, 'Have PQexecParams');
|
||||
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 {
|
||||
|
|
|
@ -232,7 +232,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
if (S->cursor_name) {
|
||||
efree(S->cursor_name);
|
||||
}
|
||||
spprintf(&S->cursor_name, 0, "pdo_pgsql_cursor_%08x", (unsigned int) stmt);
|
||||
spprintf(&S->cursor_name, 0, "pdo_crsr_%016lx", (unsigned long) stmt);
|
||||
#if HAVE_PQPREPARE
|
||||
emulate = 1;
|
||||
#endif
|
||||
|
@ -264,7 +264,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
spprintf(&S->stmt_name, 0, "pdo_pgsql_stmt_%08x", (unsigned int)stmt);
|
||||
spprintf(&S->stmt_name, 0, "pdo_stmt_%016lx", (unsigned long)stmt);
|
||||
/* that's all for now; we'll defer the actual prepare until the first execute call */
|
||||
|
||||
if (nsql) {
|
||||
|
@ -300,9 +300,7 @@ static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRM
|
|||
return -1;
|
||||
}
|
||||
H->pgoid = PQoidValue(res);
|
||||
#if HAVE_PQCMDTUPLES
|
||||
ret = atol(PQcmdTuples(res));
|
||||
#endif
|
||||
PQclear(res);
|
||||
|
||||
return ret;
|
||||
|
@ -312,16 +310,17 @@ 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, unquoted, unquotedlen, quotedlen);
|
||||
escaped = PQescapeByteaConn(H->server, unquoted, unquotedlen, &tmp_len);
|
||||
#else
|
||||
escaped = PQescapeBytea(unquoted, unquotedlen, quotedlen);
|
||||
escaped = PQescapeBytea(unquoted, unquotedlen, &tmp_len);
|
||||
#endif
|
||||
*quotedlen += 1;
|
||||
*quotedlen = (int)tmp_len + 1;
|
||||
*quoted = emalloc(*quotedlen + 1);
|
||||
memcpy((*quoted)+1, escaped, *quotedlen-2);
|
||||
(*quoted)[0] = '\'';
|
||||
|
@ -402,11 +401,9 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value
|
|||
break;
|
||||
|
||||
case PDO_ATTR_SERVER_VERSION:
|
||||
#ifdef HAVE_PQPROTOCOLVERSION
|
||||
if (PQprotocolVersion(H->server) >= 3) { /* PostgreSQL 7.4 or later */
|
||||
ZVAL_STRING(return_value, (char*)PQparameterStatus(H->server, "server_version"), 1);
|
||||
} else /* emulate above via a query */
|
||||
#endif
|
||||
{
|
||||
PGresult *res = PQexec(H->server, "SELECT VERSION()");
|
||||
if (res && PQresultStatus(res) == PGRES_TUPLES_OK) {
|
||||
|
@ -456,7 +453,6 @@ 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;
|
||||
#ifdef HAVE_PQPROTOCOLVERSION
|
||||
spprintf(&tmp, 0,
|
||||
"PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
|
||||
spid,
|
||||
|
@ -464,9 +460,6 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value
|
|||
(char*)PQparameterStatus(H->server, "is_superuser"),
|
||||
(char*)PQparameterStatus(H->server, "session_authorization"),
|
||||
(char*)PQparameterStatus(H->server, "DateStyle"));
|
||||
#else
|
||||
spprintf(&tmp, 0, "PID: %d", spid);
|
||||
#endif
|
||||
ZVAL_STRING(return_value, tmp, 0);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -175,7 +175,7 @@ stmt_retry:
|
|||
* deallocate it and retry ONCE (thies 2005.12.15)
|
||||
*/
|
||||
if (!strcmp(sqlstate, "42P05")) {
|
||||
char buf[100]; /* stmt_name == "pdo_pgsql_cursor_%08x" */
|
||||
char buf[100]; /* stmt_name == "pdo_crsr_%016lx" */
|
||||
PGresult *res;
|
||||
snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
|
||||
res = PQexec(H->server, buf);
|
||||
|
@ -467,110 +467,6 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* PQunescapeBytea() from PostgreSQL 7.3 to provide bytea unescape feature to 7.2 users.
|
||||
Renamed to php_pdo_pgsql_unescape_bytea() */
|
||||
/*
|
||||
* PQunescapeBytea - converts the null terminated string representation
|
||||
* of a bytea, strtext, into binary, filling a buffer. It returns a
|
||||
* pointer to the buffer which is NULL on error, and the size of the
|
||||
* buffer in retbuflen. The pointer may subsequently be used as an
|
||||
* argument to the function free(3). It is the reverse of PQescapeBytea.
|
||||
*
|
||||
* The following transformations are reversed:
|
||||
* '\0' == ASCII 0 == \000
|
||||
* '\'' == ASCII 39 == \'
|
||||
* '\\' == ASCII 92 == \\
|
||||
*
|
||||
* States:
|
||||
* 0 normal 0->1->2->3->4
|
||||
* 1 \ 1->5
|
||||
* 2 \0 1->6
|
||||
* 3 \00
|
||||
* 4 \000
|
||||
* 5 \'
|
||||
* 6 \\
|
||||
*/
|
||||
static unsigned char *php_pdo_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen)
|
||||
{
|
||||
size_t buflen;
|
||||
unsigned char *buffer,
|
||||
*sp,
|
||||
*bp;
|
||||
unsigned int state = 0;
|
||||
|
||||
if (strtext == NULL)
|
||||
return NULL;
|
||||
buflen = strlen(strtext); /* will shrink, also we discover if
|
||||
* strtext */
|
||||
buffer = (unsigned char *) emalloc(buflen); /* isn't NULL terminated */
|
||||
for (bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
if (*sp == '\\')
|
||||
state = 1;
|
||||
*bp = *sp;
|
||||
break;
|
||||
case 1:
|
||||
if (*sp == '\'') /* state=5 */
|
||||
{ /* replace \' with 39 */
|
||||
bp--;
|
||||
*bp = '\'';
|
||||
buflen--;
|
||||
state = 0;
|
||||
}
|
||||
else if (*sp == '\\') /* state=6 */
|
||||
{ /* replace \\ with 92 */
|
||||
bp--;
|
||||
*bp = '\\';
|
||||
buflen--;
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isdigit(*sp))
|
||||
state = 2;
|
||||
else
|
||||
state = 0;
|
||||
*bp = *sp;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (isdigit(*sp))
|
||||
state = 3;
|
||||
else
|
||||
state = 0;
|
||||
*bp = *sp;
|
||||
break;
|
||||
case 3:
|
||||
if (isdigit(*sp)) /* state=4 */
|
||||
{
|
||||
unsigned char *start, *end, buf[4]; /* 000 + '\0' */
|
||||
|
||||
bp -= 3;
|
||||
memcpy(buf, sp-2, 3);
|
||||
buf[3] = '\0';
|
||||
start = buf;
|
||||
*bp = (unsigned char)strtoul(start, (char **)&end, 8);
|
||||
buflen -= 3;
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bp = *sp;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer = erealloc(buffer, buflen+1);
|
||||
buffer[buflen] = '\0';
|
||||
|
||||
*retbuflen = buflen;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
|
@ -618,12 +514,20 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
|
|||
*len = 0;
|
||||
return 0;
|
||||
} else {
|
||||
*ptr = php_pdo_pgsql_unescape_bytea(*ptr, &tmp_len);
|
||||
char *tmp_ptr = PQunescapeBytea(*ptr, &tmp_len);
|
||||
if (!tmp_ptr) {
|
||||
/* PQunescapeBytea returned an error */
|
||||
*len = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!tmp_len) {
|
||||
/* Empty string, return as empty stream */
|
||||
*ptr = (char *)php_stream_memory_open(TEMP_STREAM_READONLY, "", 0);
|
||||
PQfreemem(tmp_ptr);
|
||||
*len = 0;
|
||||
} else {
|
||||
*ptr = estrndup(tmp_ptr, tmp_len);
|
||||
PQfreemem(tmp_ptr);
|
||||
*len = tmp_len;
|
||||
*caller_frees = 1;
|
||||
}
|
||||
|
|
|
@ -81,11 +81,7 @@ extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const
|
|||
|
||||
extern struct pdo_stmt_methods pgsql_stmt_methods;
|
||||
|
||||
#ifdef HAVE_PQRESULTERRORFIELD
|
||||
#define pdo_pgsql_sqlstate(r) PQresultErrorField(r, PG_DIAG_SQLSTATE)
|
||||
#else
|
||||
#define pdo_pgsql_sqlstate(r) (const char *)NULL
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT = PDO_ATTR_DRIVER_SPECIFIC,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue