From b1ffea3ccce0e1f1a63022f446c1549dfad92e9e Mon Sep 17 00:00:00 2001 From: Matteo Beccati Date: Sun, 9 Mar 2014 11:43:13 +0100 Subject: Drop PDO support for extremely old libpq versions configure will now fail if any of the following function is missing: * PQprepare * PQexecParams * PQescapeStringConn * PQescapeByteaConn --- ext/pdo_pgsql/pgsql_driver.c | 45 +++++++++++++------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) (limited to 'ext/pdo_pgsql/pgsql_driver.c') 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) { -- cgit v1.2.1 From d72621ab9e8a6cc89fe1005a83c16249fdc02810 Mon Sep 17 00:00:00 2001 From: Matteo Beccati Date: Sun, 9 Mar 2014 12:14:23 +0100 Subject: Deprecated PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT --- ext/pdo_pgsql/pgsql_driver.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ext/pdo_pgsql/pgsql_driver.c') diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index b1fa4f88f5..0d72d5573e 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -239,8 +239,11 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter); emulate = 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 || - pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, H->emulate_prepares TSRMLS_CC) == 1) { + 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; } } else { @@ -1106,6 +1109,7 @@ static int pdo_pgsql_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC) 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; default: -- cgit v1.2.1 From e378348a316008822737d47cf47a4938cbc07dd6 Mon Sep 17 00:00:00 2001 From: Matteo Beccati Date: Sun, 9 Mar 2014 14:08:17 +0100 Subject: Added new PDO::PGSQL_ATTR_DISABLE_PREPARES that uses PQexecParams Faster than prepared statements when queries are run once. Slightly slower than PDO::ATTR_EMULATE_PREPARES but without the potential security implications of embedding parameters in the query itself. --- ext/pdo_pgsql/pgsql_driver.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'ext/pdo_pgsql/pgsql_driver.c') diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 0d72d5573e..96f6fa7f72 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -224,6 +224,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, char *nsql = NULL; int nsql_len = 0; int emulate = 0; + int execute_only = 0; S->H = H; stmt->driver_data = S; @@ -246,8 +247,12 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, 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) { @@ -264,8 +269,11 @@ 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; @@ -1112,6 +1120,9 @@ static int pdo_pgsql_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC) 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; + case PDO_PGSQL_ATTR_DISABLE_PREPARES: + H->disable_prepares = Z_LVAL_P(val); + return 1; default: return 0; } -- cgit v1.2.1