diff options
author | Matteo Beccati <mbeccati@php.net> | 2014-03-09 11:43:13 +0100 |
---|---|---|
committer | Matteo Beccati <mbeccati@php.net> | 2014-03-11 23:10:47 +0100 |
commit | b1ffea3ccce0e1f1a63022f446c1549dfad92e9e (patch) | |
tree | 51469590f6a27d8976e636f2781e8e6bb17add9d /ext/pdo_pgsql | |
parent | 1a14eb53c4c7bff343e0df9463c6b109c0d9f469 (diff) | |
download | php-git-b1ffea3ccce0e1f1a63022f446c1549dfad92e9e.tar.gz |
Drop PDO support for extremely old libpq versions
configure will now fail if any of the following function is missing:
* PQprepare
* PQexecParams
* PQescapeStringConn
* PQescapeByteaConn
Diffstat (limited to 'ext/pdo_pgsql')
-rw-r--r-- | ext/pdo_pgsql/config.m4 | 20 | ||||
-rw-r--r-- | ext/pdo_pgsql/config.w32 | 5 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 45 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_statement.c | 74 | ||||
-rw-r--r-- | ext/pdo_pgsql/php_pdo_pgsql_int.h | 6 |
5 files changed, 53 insertions, 97 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/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 9b083f6545..b1fa4f88f5 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,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) { diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index ea5a67633e..02fc1d6e90 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,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(¶m->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(¶m->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(¶m->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; } diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 908f47d57c..037344ab94 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. */ 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; |