summaryrefslogtreecommitdiff
path: root/ext/pdo_pgsql
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2010-03-09 11:57:54 +0100
committerOndřej Surý <ondrej@sury.org>2010-03-09 11:57:54 +0100
commit855a09f4eded707941180c9d90acd17c25e29447 (patch)
treea40947efaa9876f31b6ee3956c3f3775768143bb /ext/pdo_pgsql
parentc852c28a88fccf6e34a2cb091fdfa72bce2b59c7 (diff)
downloadphp-855a09f4eded707941180c9d90acd17c25e29447.tar.gz
Imported Upstream version 5.3.2upstream/5.3.2
Diffstat (limited to 'ext/pdo_pgsql')
-rw-r--r--ext/pdo_pgsql/config.m42
-rw-r--r--ext/pdo_pgsql/pdo_pgsql.c8
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c36
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c6
-rw-r--r--ext/pdo_pgsql/php_pdo_pgsql.h4
-rw-r--r--ext/pdo_pgsql/php_pdo_pgsql_int.h12
-rw-r--r--ext/pdo_pgsql/tests/bug48764.phpt134
-rw-r--r--ext/pdo_pgsql/tests/bug_33876.phpt10
-rw-r--r--ext/pdo_pgsql/tests/bug_49985.phpt35
9 files changed, 220 insertions, 27 deletions
diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4
index 8e55524f5..f75d79196 100644
--- a/ext/pdo_pgsql/config.m4
+++ b/ext/pdo_pgsql/config.m4
@@ -1,4 +1,4 @@
-dnl $Id: config.m4 279602 2009-04-30 12:38:43Z mbeccati $
+dnl $Id: config.m4 291414 2009-11-29 06:13:22Z rasmus $
dnl config.m4 for extension pdo_pgsql
dnl vim:et:sw=2:ts=2:
diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c
index 40856557c..1be19cef7 100644
--- a/ext/pdo_pgsql/pdo_pgsql.c
+++ b/ext/pdo_pgsql/pdo_pgsql.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 The PHP Group |
+ | Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_pgsql.c 277898 2009-03-28 01:58:49Z mbeccati $ */
+/* $Id: pdo_pgsql.c 293036 2010-01-03 09:23:27Z sebastian $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -85,8 +85,8 @@ ZEND_GET_MODULE(pdo_pgsql)
*/
PHP_MINIT_FUNCTION(pdo_pgsql)
{
- php_pdo_register_driver(&pdo_pgsql_driver);
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT", PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT);
+ php_pdo_register_driver(&pdo_pgsql_driver);
return SUCCESS;
}
/* }}} */
@@ -128,7 +128,7 @@ PHP_MINFO_FUNCTION(pdo_pgsql)
php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION);
#endif
php_info_print_table_row(2, "Module version", pdo_pgsql_module_entry.version);
- php_info_print_table_row(2, "Revision", " $Id: pdo_pgsql.c 277898 2009-03-28 01:58:49Z mbeccati $ ");
+ php_info_print_table_row(2, "Revision", " $Id: pdo_pgsql.c 293036 2010-01-03 09:23:27Z sebastian $ ");
php_info_print_table_end();
}
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index ef720cdac..32fd472e9 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 The PHP Group |
+ | Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql_driver.c 279604 2009-04-30 12:56:00Z mbeccati $ */
+/* $Id: pgsql_driver.c 294444 2010-02-03 19:48:04Z pajoye $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -87,7 +87,7 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *
}
if (!dbh->methods) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
+ zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
*pdo_err, einfo->errcode, einfo->errmsg);
}
@@ -232,22 +232,20 @@ 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_crsr_%016lx", (unsigned long) stmt);
+ spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter);
#if HAVE_PQPREPARE
emulate = 1;
#endif
}
#if HAVE_PQPREPARE
-
else if (driver_options) {
- if (pdo_attr_lval(driver_options,
- PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 0 TSRMLS_CC) == 1) {
- emulate = 1;
- } else if (pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES,
- 0 TSRMLS_CC) == 1) {
+ 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;
}
+ } else {
+ emulate = H->disable_native_prepares || H->emulate_prepares;
}
if (!emulate && PQprotocolVersion(H->server) > 2) {
@@ -264,7 +262,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
return 0;
}
- spprintf(&S->stmt_name, 0, "pdo_stmt_%016lx", (unsigned long)stmt);
+ 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) {
@@ -625,7 +623,21 @@ static const zend_function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, i
static int pdo_pgsql_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
{
- return 0;
+ 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;
+ }
}
static struct pdo_dbh_methods pgsql_methods = {
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index 85ae91367..8f2c8f85c 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 The PHP Group |
+ | Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql_statement.c 281107 2009-05-25 19:41:13Z kalle $ */
+/* $Id: pgsql_statement.c 293036 2010-01-03 09:23:27Z sebastian $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -185,7 +185,7 @@ stmt_retry:
* deallocate it and retry ONCE (thies 2005.12.15)
*/
if (!strcmp(sqlstate, "42P05")) {
- char buf[100]; /* stmt_name == "pdo_crsr_%016lx" */
+ char buf[100]; /* stmt_name == "pdo_crsr_%08x" */
PGresult *res;
snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
res = PQexec(H->server, buf);
diff --git a/ext/pdo_pgsql/php_pdo_pgsql.h b/ext/pdo_pgsql/php_pdo_pgsql.h
index 1760d61b4..9cdb176fd 100644
--- a/ext/pdo_pgsql/php_pdo_pgsql.h
+++ b/ext/pdo_pgsql/php_pdo_pgsql.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 The PHP Group |
+ | Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_pgsql.h 272370 2008-12-31 11:15:49Z sebastian $ */
+/* $Id: php_pdo_pgsql.h 293036 2010-01-03 09:23:27Z sebastian $ */
#ifndef PHP_PDO_PGSQL_H
#define PHP_PDO_PGSQL_H
diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h
index fb0a95ec3..a9c686ba1 100644
--- a/ext/pdo_pgsql/php_pdo_pgsql_int.h
+++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 The PHP Group |
+ | Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_pgsql_int.h 280407 2009-05-12 22:18:15Z mbeccati $ */
+/* $Id: php_pdo_pgsql_int.h 293036 2010-01-03 09:23:27Z sebastian $ */
#ifndef PHP_PDO_PGSQL_INT_H
#define PHP_PDO_PGSQL_INT_H
@@ -43,6 +43,14 @@ 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;
} pdo_pgsql_db_handle;
typedef struct {
diff --git a/ext/pdo_pgsql/tests/bug48764.phpt b/ext/pdo_pgsql/tests/bug48764.phpt
new file mode 100644
index 000000000..67e8f3971
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug48764.phpt
@@ -0,0 +1,134 @@
+--TEST--
+Bug #48764 (PDO_pgsql::query always uses implicit prepared statements if v3 proto available)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+
+$db = PDOTest::factory();
+
+$client_version = $db->getAttribute(PDO::ATTR_CLIENT_VERSION);
+$server_version = $db->getAttribute(PDO::ATTR_SERVER_VERSION);
+
+if (version_compare($server_version, '7.4', '<') || version_compare($client_version, '7.4', '<')) {
+ die('skip');
+}
+
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+echo "Test 1\n";
+bug($db);
+
+echo "Test 2\n";
+bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0));
+bug($db, array(PDO::ATTR_EMULATE_PREPARES => 1));
+
+echo "Test 3\n";
+bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0));
+bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 1));
+
+echo "Test 4\n";
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
+bug($db);
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
+bug($db);
+
+echo "Test 5\n";
+$db->setAttribute(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 1);
+bug($db);
+$db->setAttribute(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 0);
+bug($db);
+
+
+putenv('PDOTEST_ATTR='.serialize(array(
+ PDO::ATTR_EMULATE_PREPARES => 1,
+)));
+$db = PDOTest::factory('PDO', false);
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+echo "Test 6\n";
+bug($db);
+bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0));
+bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0));
+
+
+putenv('PDOTEST_ATTR='.serialize(array(
+ PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 1,
+)));
+
+$db = PDOTest::factory('PDO', false);
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+echo "Test 7\n";
+bug($db);
+bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0));
+bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0));
+
+
+putenv('PDOTEST_ATTR='.serialize(array(
+ PDO::ATTR_EMULATE_PREPARES => 1,
+ PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 1,
+)));
+
+$db = PDOTest::factory('PDO', false);
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+echo "Test 8\n";
+bug($db);
+bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0));
+bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0));
+bug($db, array(
+ PDO::ATTR_EMULATE_PREPARES => 0,
+ PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0,
+));
+
+
+putenv('PDOTEST_ATTR');
+
+
+function bug($db, $options = array()) {
+ try {
+ $stmt = $db->prepare("SELECT ?", $options);
+ $stmt->execute(array(1));
+ echo "OK\n";
+ } catch (PDOException $e) {
+ // Indetermined data type when using native prepared statements
+ echo $e->getCode()."\n";
+ }
+}
+
+--EXPECT--
+Test 1
+42P18
+Test 2
+42P18
+OK
+Test 3
+42P18
+OK
+Test 4
+OK
+42P18
+Test 5
+OK
+42P18
+Test 6
+OK
+42P18
+OK
+Test 7
+OK
+OK
+42P18
+Test 8
+OK
+OK
+OK
+42P18
diff --git a/ext/pdo_pgsql/tests/bug_33876.phpt b/ext/pdo_pgsql/tests/bug_33876.phpt
index 0ec04e8bd..48618e13d 100644
--- a/ext/pdo_pgsql/tests/bug_33876.phpt
+++ b/ext/pdo_pgsql/tests/bug_33876.phpt
@@ -80,10 +80,14 @@ else
# Expected to fail; unless told otherwise, PDO assumes string inputs
# false -> "" as string, which pgsql doesn't like
-if (!$res->execute(array(false)))
- print_r($res->errorInfo());
-else
+if (!$res->execute(array(false))) {
+ $err = $res->errorInfo();
+ // Strip additional lines ouputted by recent PgSQL versions
+ $err[2] = trim(current(explode("\n", $err[2])));
+ print_r($err);
+} else {
print_r($res->fetchAll(PDO::FETCH_ASSOC));
+}
diff --git a/ext/pdo_pgsql/tests/bug_49985.phpt b/ext/pdo_pgsql/tests/bug_49985.phpt
new file mode 100644
index 000000000..26dcfc617
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug_49985.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$db->exec("CREATE TABLE test (a int PRIMARY KEY)");
+
+for ($i = 0; $i < 3; $i++) {
+ try {
+ $db->beginTransaction();
+ $stmt = $db->prepare("INSERT INTO test (a) VALUES (?)");
+ var_dump($stmt->execute(array(1)));
+ $db->commit();
+ } catch (Exception $e) {
+ echo trim(current(explode("\n", $e->getMessage())))."\n";
+ $db->rollback();
+ }
+}
+
+?>
+--EXPECTF--
+bool(true)
+SQLSTATE[23505]: %s"test_pkey"
+SQLSTATE[23505]: %s"test_pkey"
+