]> granicus.if.org Git - php/commitdiff
Fixed bug #67462 PDO_PGSQL::beginTransaction() wrongly throws exception when not...
authorMatteo Beccati <mbeccati@php.net>
Fri, 31 Oct 2014 17:10:01 +0000 (18:10 +0100)
committerMatteo Beccati <mbeccati@php.net>
Fri, 31 Oct 2014 17:11:32 +0000 (18:11 +0100)
NEWS
ext/pdo_pgsql/pgsql_driver.c
ext/pdo_pgsql/tests/bug67462.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 9e5e1388c81aa41668d8cb71bdc4993ccbdda8d0..ec68e1d7304650032aa0507eb27d7923346acea7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,10 @@ PHP                                                                        NEWS
   . Fixed bug #68087 (ODBC not correctly reading DATE column when preceded by
     a VARCHAR column) (Keyur Govande)
 
+- PDO_pgsql:
+  . Fixed bug #67462 (PDO_PGSQL::beginTransaction() wrongly throws exception
+    when not in transaction) (Matteo)
+
 - SPL:
   . Fixed bug #68128 (Regression in RecursiveRegexIterator) (Tjerk)
 
index 3be9359216de8ed3bb7d59554448b4bc1c7d060f..9638c72fe62bfb68953349b22134c48a9faf559f 100644 (file)
@@ -465,6 +465,15 @@ static int pdo_pgsql_check_liveness(pdo_dbh_t *dbh TSRMLS_DC)
 }
 /* }}} */
 
+static int pgsql_handle_in_transaction(pdo_dbh_t *dbh TSRMLS_DC)
+{
+       pdo_pgsql_db_handle *H;
+
+       H = (pdo_pgsql_db_handle *)dbh->driver_data;
+
+       return PQtransactionStatus(H->server) > PQTRANS_IDLE;
+}
+
 static int pdo_pgsql_transaction_cmd(const char *cmd, pdo_dbh_t *dbh TSRMLS_DC)
 {
        pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
@@ -489,7 +498,15 @@ static int pgsql_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
 
 static int pgsql_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
 {
-       return pdo_pgsql_transaction_cmd("COMMIT", dbh TSRMLS_CC);
+       int ret = pdo_pgsql_transaction_cmd("COMMIT", dbh TSRMLS_CC);
+
+       /* When deferred constraints are used the commit could
+          fail, and a ROLLBACK implicitly ran. See bug #67462 */
+       if (!ret) {
+               dbh->in_txn = pgsql_handle_in_transaction(dbh);
+       }
+
+       return ret;
 }
 
 static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
@@ -497,15 +514,6 @@ static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
        return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
 }
 
-static int pgsql_handle_in_transaction(pdo_dbh_t *dbh TSRMLS_DC)
-{
-       pdo_pgsql_db_handle *H;
-
-       H = (pdo_pgsql_db_handle *)dbh->driver_data;
-
-       return PQtransactionStatus(H->server);
-}
-
 /* {{{ proto string PDO::pgsqlCopyFromArray(string $table_name , array $rows [, string $delimiter [, string $null_as ] [, string $fields])
    Returns true if the copy worked fine or false if error */
 static PHP_METHOD(PDO, pgsqlCopyFromArray)
diff --git a/ext/pdo_pgsql/tests/bug67462.phpt b/ext/pdo_pgsql/tests/bug67462.phpt
new file mode 100644 (file)
index 0000000..888b19c
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+PDO PgSQL Bug #67462 (PDO_PGSQL::beginTransaction() wrongly throws exception when not in 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';
+$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+$pdo->beginTransaction();
+
+try {
+       $pdo->query("CREATE TABLE b67462 (a int NOT NULL PRIMARY KEY DEFERRABLE INITIALLY DEFERRED)");
+       $pdo->query("INSERT INTO b67462 VALUES (1), (1)");
+
+       var_dump($pdo->inTransaction());
+       $pdo->commit(); // This should fail!
+} catch (\Exception $e) {
+       var_dump($pdo->inTransaction());
+       var_dump($pdo->beginTransaction());
+}
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)