]> granicus.if.org Git - php/commitdiff
Drop PDO support for extremely old libpq versions
authorMatteo Beccati <mbeccati@php.net>
Sun, 9 Mar 2014 10:43:13 +0000 (11:43 +0100)
committerMatteo Beccati <mbeccati@php.net>
Tue, 11 Mar 2014 22:10:47 +0000 (23:10 +0100)
configure will now fail if any of the following function is missing:
* PQprepare
* PQexecParams
* PQescapeStringConn
* PQescapeByteaConn

ext/pdo_pgsql/config.m4
ext/pdo_pgsql/config.w32
ext/pdo_pgsql/pgsql_driver.c
ext/pdo_pgsql/pgsql_statement.c
ext/pdo_pgsql/php_pdo_pgsql_int.h

index afe42e06a5be51a2d6b7ae9a59ef21c3d5c775ff..c61c5de4f4239d2ea99c08d4f9933f50966eb389 100644 (file)
@@ -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
index 223780e3f96529ce4b720fc9e0be84a61176ba69..2097dc2da91e139e0091a045a9dcd4a2925bf805 100644 (file)
@@ -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");
index 9b083f65455a7d039dec11c1a4d3b54ec42f00c8..b1fa4f88f58530a806f953938d616e1b0941dfaa 100644 (file)
@@ -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,10 @@ 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
 
        S->H = H;
        stmt->driver_data = S;
@@ -239,13 +237,8 @@ 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) {
+       } 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) {
                        emulate = 1;
@@ -270,7 +263,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
 
                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 (nsql) {
                        S->query = nsql;
                } else {
@@ -279,7 +272,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 +283,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 +307,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 +323,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 +425,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 +437,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 +561,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 +857,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, 1);
                                PQfreemem(csv);
                        } else {
@@ -951,7 +935,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 +1102,12 @@ 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:
                        H->disable_native_prepares = Z_LVAL_P(val);
                        return 1;
-#endif
-
                default:
                        return 0;
        }
@@ -1163,7 +1144,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 +1214,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) {
index ea5a67633e6ae8915ce7c6da15bd4607ede33666..02fc1d6e90ee7f61455f06bbaea57179ed98278f 100644 (file)
@@ -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,7 @@ stmt_retry:
                                S->param_lengths,
                                S->param_formats,
                                0);
-       } else
-#endif
-       {
+       } else {
                S->result = PQexec(H->server, stmt->active_query_string);
        }
        status = PQresultStatus(S->result);
@@ -238,7 +232,6 @@ 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) {
@@ -320,10 +313,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 +355,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 +387,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 +420,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 +430,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 +494,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 +508,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 +562,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 +578,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 +595,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), 1);
 done:
-       PQclear(res);           
+       PQclear(res);
        return 1;
 }
 
index 908f47d57c0efdef2fe48133706e8d7da3ed7ba9..037344ab943398d47dc77487304c671ac29d4abc 100644 (file)
@@ -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. */
        int             emulate_prepares;
        int             disable_native_prepares;
-#endif
-       unsigned int stmt_counter;
+       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;