summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Beccati <mbeccati@php.net>2009-11-04 19:32:27 +0000
committerMatteo Beccati <mbeccati@php.net>2009-11-04 19:32:27 +0000
commit72997aa430df5c998608b7612d17dc5980118208 (patch)
tree56ee25d181cad88329809ad266f518ea2e9d665c
parent2f4f36f1eebde910d910c9069dc6a5a4528082d3 (diff)
downloadphp-git-72997aa430df5c998608b7612d17dc5980118208.tar.gz
- Properly fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction).
# Removed usage of the memory address when generating prepared statemend names # as uniqueness can't be enforced. Used a statment counter instead.
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c4
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c2
-rw-r--r--ext/pdo_pgsql/php_pdo_pgsql_int.h1
-rw-r--r--ext/pdo_pgsql/tests/bug_49985.phpt35
4 files changed, 39 insertions, 3 deletions
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index cd13fc36ef..c844abbc32 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -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_crsr_%016lx", (unsigned long) stmt);
+ spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter);
#if HAVE_PQPREPARE
emulate = 1;
#endif
@@ -262,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) {
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index f19a6646c6..c465c3f7d5 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -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_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h
index 4471a80ac4..2d6b812cad 100644
--- a/ext/pdo_pgsql/php_pdo_pgsql_int.h
+++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h
@@ -50,6 +50,7 @@ typedef struct {
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/bug_49985.phpt b/ext/pdo_pgsql/tests/bug_49985.phpt
new file mode 100644
index 0000000000..7ada87630a
--- /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 $e->getMessage()."\n";
+ $db->rollback();
+ }
+}
+
+?>
+--EXPECTF--
+bool(true)
+SQLSTATE[23505]: %s"test_pkey"
+SQLSTATE[23505]: %s"test_pkey"
+