]> granicus.if.org Git - php/commitdiff
- Properly fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction).
authorMatteo Beccati <mbeccati@php.net>
Wed, 4 Nov 2009 19:32:27 +0000 (19:32 +0000)
committerMatteo Beccati <mbeccati@php.net>
Wed, 4 Nov 2009 19:32:27 +0000 (19:32 +0000)
# Removed usage of the memory address when generating prepared statemend names
# as uniqueness can't be enforced. Used a statment counter instead.

NEWS
ext/pdo_pgsql/pgsql_driver.c
ext/pdo_pgsql/pgsql_statement.c
ext/pdo_pgsql/php_pdo_pgsql_int.h
ext/pdo_pgsql/tests/bug_49985.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index da42349173047eb5a0c2b66b0052cf1a8986a9de..b88fff517183d769ca182849ebf4682da0ffcfc6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,7 +28,7 @@ PHP                                                                        NEWS
 - Fixed bug #49990 (SNMP3 warning message about security level printed twice).
   (Jani)
 - Fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted
-  transaction). (ben dot pineau at gmail dot com, Ilia)  
+  transaction). (ben dot pineau at gmail dot com, Ilia, Matteo)  
 - Fixed bug #49921 (Curl post upload functions changed). (Ilia)
 - Fixed bug #49855 (import_request_variables() always returns NULL). (Ilia,
   sjoerd at php dot net)
index 7ccbe09b3e25bc65020343091d0626b95b5596c2..deeddb79514a48d9d7e727a28e88928a660cd84d 100644 (file)
@@ -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) {
index bf7e33448e2b32c9a53562a6bc73c16b6c1ba78f..b5c7f42eea37947f79702effbbcd2c697601738d 100644 (file)
@@ -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);
index 50b478f340bf8f7833ead83ce7e52af3aad4ceb4..71b6909138686c835a00e5308a69fbe0775a5e96 100644 (file)
@@ -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 (file)
index 0000000..7ada876
--- /dev/null
@@ -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"
+