diff --git a/ext/pdo/tests/pdo_017.phpt b/ext/pdo/tests/pdo_017.phpt index bc514bff2c32b..d24aff1c15f32 100644 --- a/ext/pdo/tests/pdo_017.phpt +++ b/ext/pdo/tests/pdo_017.phpt @@ -8,7 +8,6 @@ $dir = getenv('REDIR_TEST_DIR'); if (false == $dir) die('skip no driver'); require_once $dir . 'pdo_test.inc'; PDOTest::skip(); -if (str_starts_with(getenv('PDOTEST_DSN'), "firebird")) die('xfail firebird driver does not behave as expected'); $db = PDOTest::factory(); try { diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index bb9eb29ee9166..8b4572970a23f 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -33,6 +33,7 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t*, const zend_string*, XSQLDA*, isc_stmt_handle*, HashTable*); +static bool php_firebird_rollback_transaction(pdo_dbh_t *dbh); const char CHR_LETTER = 1; const char CHR_DIGIT = 2; @@ -526,17 +527,14 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; - if (dbh->in_txn) { + if (H->tr) { if (dbh->auto_commit) { - if (isc_commit_transaction(H->isc_status, &H->tr)) { - php_firebird_error(dbh); - } + php_firebird_commit_transaction(dbh, /* release */ false); } else { - if (isc_rollback_transaction(H->isc_status, &H->tr)) { - php_firebird_error(dbh); - } + php_firebird_rollback_transaction(dbh); } } + H->in_manually_txn = 0; if (isc_detach_database(H->isc_status, &H->db)) { php_firebird_error(dbh); @@ -702,9 +700,10 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /* } } - /* commit if we're in auto_commit mode */ - if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) { - php_firebird_error(dbh); + if (dbh->auto_commit && !H->in_manually_txn) { + if (!php_firebird_commit_transaction(dbh, /* retain */ true)) { + ret = -1; + } } free_statement: @@ -756,8 +755,8 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un } /* }}} */ -/* called by PDO to start a transaction */ -static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */ +/* php_firebird_begin_transaction */ +static bool php_firebird_begin_transaction(pdo_dbh_t *dbh) /* {{{ */ { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; char tpb[8] = { isc_tpb_version3 }, *ptpb = tpb+1; @@ -809,12 +808,84 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */ } /* }}} */ +/* called by PDO to start a transaction */ +static bool firebird_handle_manually_begin(pdo_dbh_t *dbh) /* {{{ */ +{ + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; + + /** + * If in autocommit mode and in transaction, we will need to close the transaction once. + */ + if (dbh->auto_commit && H->tr) { + if (!php_firebird_commit_transaction(dbh, /* release */ false)) { + return false; + } + } + + if (!php_firebird_begin_transaction(dbh)) { + return false; + } + H->in_manually_txn = 1; + return true; +} +/* }}} */ + +/* php_firebird_commit_transaction */ +bool php_firebird_commit_transaction(pdo_dbh_t *dbh, bool retain) /* {{{ */ +{ + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; + + /** + * `retaining` keeps the transaction open without closing it. + * + * firebird needs to always have a transaction open to emulate autocommit mode, + * and in autocommit mode it keeps the transaction open. + * + * Same as close and then begin again, but use retain to save overhead. + */ + if (retain) { + if (isc_commit_retaining(H->isc_status, &H->tr)) { + php_firebird_error(dbh); + return false; + } + } else { + if (isc_commit_transaction(H->isc_status, &H->tr)) { + php_firebird_error(dbh); + return false; + } + } + return true; +} +/* }}} */ + /* called by PDO to commit a transaction */ -static bool firebird_handle_commit(pdo_dbh_t *dbh) /* {{{ */ +static bool firebird_handle_manually_commit(pdo_dbh_t *dbh) /* {{{ */ +{ + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; + if (!php_firebird_commit_transaction(dbh, /*release*/ false)) { + return false; + } + + /** + * If in autocommit mode, begin the transaction again + * Reopen instead of retain because isolation level may change + */ + if (dbh->auto_commit) { + if (!php_firebird_begin_transaction(dbh)) { + return false; + } + } + H->in_manually_txn = 0; + return true; +} +/* }}} */ + +/* php_firebird_rollback_transaction */ +static bool php_firebird_rollback_transaction(pdo_dbh_t *dbh) /* {{{ */ { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; - if (isc_commit_transaction(H->isc_status, &H->tr)) { + if (isc_rollback_transaction(H->isc_status, &H->tr)) { php_firebird_error(dbh); return false; } @@ -823,14 +894,24 @@ static bool firebird_handle_commit(pdo_dbh_t *dbh) /* {{{ */ /* }}} */ /* called by PDO to rollback a transaction */ -static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */ +static bool firebird_handle_manually_rollback(pdo_dbh_t *dbh) /* {{{ */ { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; - if (isc_rollback_transaction(H->isc_status, &H->tr)) { - php_firebird_error(dbh); + if (!php_firebird_rollback_transaction(dbh)) { return false; } + + /** + * If in autocommit mode, begin the transaction again + * Reopen instead of retain because isolation level may change + */ + if (dbh->auto_commit) { + if (!php_firebird_begin_transaction(dbh)) { + return false; + } + } + H->in_manually_txn = 0; return true; } /* }}} */ @@ -848,16 +929,6 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq return 0; } - /* start a new transaction implicitly if auto_commit is enabled and no transaction is open */ - if (dbh->auto_commit && !dbh->in_txn) { - /* dbh->transaction_flags = PDO_TRANS_READ_UNCOMMITTED; */ - - if (!firebird_handle_begin(dbh)) { - return 0; - } - dbh->in_txn = true; - } - /* allocate the statement */ if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) { php_firebird_error(dbh); @@ -898,21 +969,34 @@ static bool pdo_firebird_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val return false; } + if (H->in_manually_txn) { + /* change auto commit mode with an open transaction is illegal, because + we won't know what to do with it */ + pdo_raise_impl_error(dbh, NULL, "HY000", "Cannot change autocommit mode while a transaction is already open"); + return false; + } + /* ignore if the new value equals the old one */ if (dbh->auto_commit ^ bval) { - if (dbh->in_txn) { - if (bval) { - /* turning on auto_commit with an open transaction is illegal, because - we won't know what to do with it */ - const char *msg = "Cannot enable auto-commit while a transaction is already open"; - php_firebird_error_with_info(dbh, "HY000", strlen("HY000"), msg, strlen(msg)); - return false; - } else { - /* close the transaction */ - if (!firebird_handle_commit(dbh)) { - break; + if (bval) { + /* change to auto commit mode. + * If the transaction is not started, start it. + * However, this is a fallback since such a situation usually does not occur. + */ + if (!H->tr) { + if (!php_firebird_begin_transaction(dbh)) { + return false; + } + } + } else { + /* change to not auto commit mode. + * close the transaction if exists. + * However, this is a fallback since such a situation usually does not occur. + */ + if (H->tr) { + if (!php_firebird_commit_transaction(dbh, /* release */ false)) { + return false; } - dbh->in_txn = false; } } dbh->auto_commit = bval; @@ -1058,14 +1142,27 @@ static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval } /* }}} */ +/* {{{ firebird_in_manually_transaction */ +static bool pdo_firebird_in_manually_transaction(pdo_dbh_t *dbh) +{ + /** + * we can tell if a transaction exists now by checking H->tr, + * but which will always be true in autocommit mode. + * So this function checks if there is currently a "manually begun transaction". + */ + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; + return H->in_manually_txn; +} +/* }}} */ + static const struct pdo_dbh_methods firebird_methods = { /* {{{ */ firebird_handle_closer, firebird_handle_preparer, firebird_handle_doer, firebird_handle_quoter, - firebird_handle_begin, - firebird_handle_commit, - firebird_handle_rollback, + firebird_handle_manually_begin, + firebird_handle_manually_commit, + firebird_handle_manually_rollback, pdo_firebird_set_attribute, NULL, /* last_id not supported */ pdo_firebird_fetch_error_func, @@ -1073,7 +1170,7 @@ static const struct pdo_dbh_methods firebird_methods = { /* {{{ */ NULL, /* check_liveness */ NULL, /* get driver methods */ NULL, /* request shutdown */ - NULL, /* in transaction, use PDO's internal tracking mechanism */ + pdo_firebird_in_manually_transaction, NULL /* get gc */ }; /* }}} */ @@ -1154,6 +1251,11 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* "HY000", H->isc_status[1], errmsg); } + H->in_manually_txn = 0; + if (dbh->auto_commit && !H->tr) { + ret = php_firebird_begin_transaction(dbh); + } + if (!ret) { firebird_handle_closer(dbh); } diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index bc973171b2f61..000c74d6dda08 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -180,8 +180,7 @@ static int pdo_firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */ ; } - /* commit? */ - if (stmt->dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) { + if (stmt->dbh->auto_commit && !S->H->in_manually_txn && !php_firebird_commit_transaction(stmt->dbh, /* retain */ true)) { break; } diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h index c7a0087ed6d9f..af598eae98ad9 100644 --- a/ext/pdo_firebird/php_pdo_firebird_int.h +++ b/ext/pdo_firebird/php_pdo_firebird_int.h @@ -66,7 +66,6 @@ typedef struct { } pdo_firebird_error_info; typedef struct { - /* the result of the last API call */ ISC_STATUS isc_status[20]; @@ -75,6 +74,7 @@ typedef struct { /* the transaction handle */ isc_tr_handle tr; + bool in_manually_txn; /* date and time format strings, can be set by the set_attribute method */ char *date_format; @@ -93,7 +93,6 @@ typedef struct { typedef struct { - /* the link that owns this statement */ pdo_firebird_db_handle *H; @@ -122,7 +121,6 @@ typedef struct { /* the output SQLDA */ XSQLDA out_sqlda; /* last member */ - } pdo_firebird_stmt; extern const pdo_driver_t pdo_firebird_driver; @@ -136,6 +134,8 @@ extern void php_firebird_set_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char #define php_firebird_error_with_info(d,e,el,m,ml) php_firebird_set_error(d, NULL, e, el, m, ml) #define php_firebird_error_stmt_with_info(s,e,el,m,ml) php_firebird_set_error(s->dbh, s, e, el, m, ml) +extern bool php_firebird_commit_transaction(pdo_dbh_t *dbh, bool retain); + enum { PDO_FB_ATTR_DATE_FORMAT = PDO_ATTR_DRIVER_SPECIFIC, PDO_FB_ATTR_TIME_FORMAT, diff --git a/ext/pdo_firebird/tests/autocommit.phpt b/ext/pdo_firebird/tests/autocommit.phpt new file mode 100644 index 0000000000000..5ba61e11f7a8d --- /dev/null +++ b/ext/pdo_firebird/tests/autocommit.phpt @@ -0,0 +1,80 @@ +--TEST-- +PDO_Firebird: auto commit +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +setAttribute(PDO::ATTR_AUTOCOMMIT, true); + +echo "create table and insert\n"; +$dbh->exec("CREATE TABLE {$table} (val INT)"); +$dbh->exec("INSERT INTO {$table} VALUES (35)"); + +echo "new connection\n"; +unset($dbh); +$dbh = new PDO(PDO_FIREBIRD_TEST_DSN, PDO_FIREBIRD_TEST_USER, PDO_FIREBIRD_TEST_PASS); + +$r = $dbh->query("SELECT * FROM {$table}"); +var_dump($r->fetchAll()); + +echo "========== not in auto commit mode ==========\n"; +echo "auto commit mode OFF\n"; +$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false); + +echo "insert, expect error\n"; +try { + $dbh->exec("INSERT INTO {$table} VALUES (35)"); +} catch (PDOException $e) { + echo $e->getMessage()."\n\n"; +} + +echo "select, expect error\n"; +try { + $r = $dbh->query("SELECT * FROM {$table}"); +} catch (PDOException $e) { + echo $e->getMessage()."\n\n"; +} + +echo "done!"; +?> +--CLEAN-- +exec("DROP TABLE autocommit_pdo_firebird"); +?> +--EXPECTF-- +========== in auto commit mode ========== +auto commit mode ON +create table and insert +new connection +array(1) { + [0]=> + array(2) { + ["VAL"]=> + int(35) + [0]=> + int(35) + } +} +========== not in auto commit mode ========== +auto commit mode OFF +insert, expect error +SQLSTATE[08003]: Connection does not exist: %s + +select, expect error +SQLSTATE[08003]: Connection does not exist: %s + +done! diff --git a/ext/pdo_firebird/tests/autocommit_change_mode.phpt b/ext/pdo_firebird/tests/autocommit_change_mode.phpt new file mode 100644 index 0000000000000..4eacdaa697535 --- /dev/null +++ b/ext/pdo_firebird/tests/autocommit_change_mode.phpt @@ -0,0 +1,134 @@ +--TEST-- +PDO_Firebird: change auto commit +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +setAttribute(PDO::ATTR_AUTOCOMMIT, true); + +echo "========== not in manually transaction ==========\n"; + +echo "auto commit ON from ON\n"; +$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true); +var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); +echo "Success\n\n"; + +echo "auto commit OFF from ON\n"; +$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false); +var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); +echo "Success\n\n"; + +echo "auto commit OFF from OFF\n"; +$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false); +var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); +echo "Success\n\n"; + +echo "auto commit ON from OFF\n"; +$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true); +var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); +echo "Success\n\n"; + +echo "========== in manually transaction ==========\n"; + +echo "begin transaction\n"; +$dbh->beginTransaction(); +echo "\n"; + +echo "auto commit ON from ON, expect error\n"; +try { + $dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true); +} catch (PDOException $e) { + var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); + echo $e->getMessage()."\n\n"; +} + +echo "auto commit OFF from ON, expect error\n"; +try { + $dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false); +} catch (PDOException $e) { + var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); + echo $e->getMessage()."\n\n"; +} + +echo "end transaction\n"; +$dbh->rollback(); + +echo "auto commit OFF\n"; +$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false); + +echo "begin transaction\n"; +$dbh->beginTransaction(); +echo "\n"; + +echo "auto commit ON from OFF, expect error\n"; +try { + $dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true); +} catch (PDOException $e) { + var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); + echo $e->getMessage()."\n\n"; +} + +echo "auto commit OFF from OFF, expect error\n"; +try { + $dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false); +} catch (PDOException $e) { + var_dump($dbh->getAttribute(PDO::ATTR_AUTOCOMMIT)); + echo $e->getMessage()."\n\n"; +} + +echo "end transaction\n"; +$dbh->rollback(); +echo "\n"; + +echo "done!"; +?> +--EXPECT-- +========== not in manually transaction ========== +auto commit ON from ON +int(1) +Success + +auto commit OFF from ON +int(0) +Success + +auto commit OFF from OFF +int(0) +Success + +auto commit ON from OFF +int(1) +Success + +========== in manually transaction ========== +begin transaction + +auto commit ON from ON, expect error +int(1) +SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open + +auto commit OFF from ON, expect error +int(1) +SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open + +end transaction +auto commit OFF +begin transaction + +auto commit ON from OFF, expect error +int(0) +SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open + +auto commit OFF from OFF, expect error +int(0) +SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open + +end transaction + +done! diff --git a/ext/pdo_firebird/tests/bug_47415.phpt b/ext/pdo_firebird/tests/bug_47415.phpt index e67a1b3f6da3a..6a7fc6ff7f77d 100644 --- a/ext/pdo_firebird/tests/bug_47415.phpt +++ b/ext/pdo_firebird/tests/bug_47415.phpt @@ -16,8 +16,6 @@ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $dbh->exec('CREATE TABLE test47415 (idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))'); $dbh->exec('INSERT INTO test47415 VALUES(0, \'String0\')'); -$dbh->commit(); - $query = "SELECT idx, txt FROM test47415 ORDER by idx"; $idx = $txt = 0; $stmt = $dbh->prepare($query); @@ -32,8 +30,6 @@ var_dump($stmt->rowCount()); $stmt = $dbh->prepare('DELETE FROM test47415'); $stmt->execute(); -$dbh->commit(); - unset($stmt); unset($dbh); ?> diff --git a/ext/pdo_firebird/tests/bug_48877.phpt b/ext/pdo_firebird/tests/bug_48877.phpt index ecdd40baa8de0..f7fa25ba1c834 100644 --- a/ext/pdo_firebird/tests/bug_48877.phpt +++ b/ext/pdo_firebird/tests/bug_48877.phpt @@ -18,7 +18,6 @@ $dbh->exec('CREATE TABLE test48877 (A integer)'); $dbh->exec("INSERT INTO test48877 VALUES ('1')"); $dbh->exec("INSERT INTO test48877 VALUES ('2')"); $dbh->exec("INSERT INTO test48877 VALUES ('3')"); -$dbh->commit(); $query = "SELECT * FROM test48877 WHERE A = :paramno"; @@ -33,7 +32,6 @@ var_dump($stmt->rowCount()); $stmt = $dbh->prepare('DELETE FROM test48877'); $stmt->execute(); -$dbh->commit(); unset($stmt); unset($dbh); diff --git a/ext/pdo_firebird/tests/bug_53280.phpt b/ext/pdo_firebird/tests/bug_53280.phpt index 4b22ec4fa162e..b1da6789ba84d 100644 --- a/ext/pdo_firebird/tests/bug_53280.phpt +++ b/ext/pdo_firebird/tests/bug_53280.phpt @@ -14,7 +14,6 @@ require("testdb.inc"); $dbh->exec('CREATE TABLE test53280(A VARCHAR(30), B VARCHAR(30), C VARCHAR(30))'); $dbh->exec("INSERT INTO test53280 VALUES ('A', 'B', 'C')"); -$dbh->commit(); $stmt1 = "SELECT B FROM test53280 WHERE A = ? AND B = ?"; $stmt2 = "SELECT B, C FROM test53280 WHERE A = ? AND B = ?"; @@ -29,7 +28,6 @@ $stmth1->execute(array('A', 'B')); $rows = $stmth1->fetchAll(); // <------- segfault var_dump($rows); -$dbh->commit(); unset($stmth1); unset($stmth2); unset($stmt); diff --git a/ext/pdo_firebird/tests/bug_62024.phpt b/ext/pdo_firebird/tests/bug_62024.phpt index 9817e550ffc44..2f8fa09a93635 100644 --- a/ext/pdo_firebird/tests/bug_62024.phpt +++ b/ext/pdo_firebird/tests/bug_62024.phpt @@ -15,8 +15,6 @@ require("testdb.inc"); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $dbh->exec("CREATE TABLE test62024 (ID INTEGER NOT NULL, TEXT VARCHAR(10))"); -$dbh->commit(); - //start actual test $sql = "insert into test62024 (id, text) values (?, ?)"; @@ -31,15 +29,11 @@ var_dump($res); $res = $sttmt->execute($args_err); var_dump($res); -$dbh->commit(); - //teardown test data $sttmt = $dbh->prepare('DELETE FROM test62024'); $sttmt->execute(); -$dbh->commit(); - unset($sttmt); unset($dbh); diff --git a/ext/pdo_firebird/tests/bug_64037.phpt b/ext/pdo_firebird/tests/bug_64037.phpt index c37268352cd28..545e6feaf6948 100644 --- a/ext/pdo_firebird/tests/bug_64037.phpt +++ b/ext/pdo_firebird/tests/bug_64037.phpt @@ -18,8 +18,6 @@ $dbh->exec("INSERT INTO test64037 (ID, TEXT, COST) VALUES (1, 'test', -1.0)"); $dbh->exec("INSERT INTO test64037 (ID, TEXT, COST) VALUES (2, 'test', -0.99)"); $dbh->exec("INSERT INTO test64037 (ID, TEXT, COST) VALUES (3, 'test', -1.01)"); -$dbh->commit(); - $query = "SELECT * from test64037 order by ID"; $stmt = $dbh->prepare($query); $stmt->execute(); @@ -32,8 +30,6 @@ var_dump($rows[2]['COST']); $stmt = $dbh->prepare('DELETE FROM test64037'); $stmt->execute(); -$dbh->commit(); - unset($stmt); unset($dbh); diff --git a/ext/pdo_firebird/tests/ddl2.phpt b/ext/pdo_firebird/tests/ddl2.phpt new file mode 100644 index 0000000000000..f258fb6f930c1 --- /dev/null +++ b/ext/pdo_firebird/tests/ddl2.phpt @@ -0,0 +1,37 @@ +--TEST-- +PDO_Firebird: DDL/transactions 2 +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +exec("CREATE TABLE test_ddl2 (val int)"); + +$dbh->beginTransaction(); +$dbh->exec("INSERT INTO test_ddl2 (val) VALUES (120)"); +$dbh->exec("CREATE TABLE test_ddl2_2 (val INT)"); +$dbh->rollback(); + +$result = $dbh->query("SELECT * FROM test_ddl2"); +var_dump($result->fetchAll()); + +unset($dbh); +echo "done\n"; +?> +--CLEAN-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); +@$dbh->exec('DROP TABLE test_ddl2'); +@$dbh->exec('DROP TABLE test_ddl2_2'); +?> +--EXPECT-- +array(0) { +} +done diff --git a/ext/pdo_firebird/tests/payload_test.phpt b/ext/pdo_firebird/tests/payload_test.phpt index 027c101d80b52..e119a4068f622 100644 --- a/ext/pdo_firebird/tests/payload_test.phpt +++ b/ext/pdo_firebird/tests/payload_test.phpt @@ -17,6 +17,9 @@ $dsn = "firebird:dbname=inet://$address/test"; $username = 'SYSDBA'; $password = 'masterkey'; -new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); +new PDO($dsn, $username, $password, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_AUTOCOMMIT => false, +]); ?> --EXPECT-- diff --git a/ext/pdo_firebird/tests/rowCount.phpt b/ext/pdo_firebird/tests/rowCount.phpt index ec6748dd143e6..d435cc10a249c 100644 --- a/ext/pdo_firebird/tests/rowCount.phpt +++ b/ext/pdo_firebird/tests/rowCount.phpt @@ -16,7 +16,6 @@ $dbh->exec('CREATE TABLE test_rowcount (A VARCHAR(10))'); $dbh->exec("INSERT INTO test_rowcount VALUES ('A')"); $dbh->exec("INSERT INTO test_rowcount VALUES ('A')"); $dbh->exec("INSERT INTO test_rowcount VALUES ('B')"); -$dbh->commit(); $query = "SELECT * FROM test_rowcount WHERE A = ?"; @@ -30,14 +29,11 @@ var_dump($stmt->rowCount()); $stmt = $dbh->prepare('UPDATE test_rowcount SET A="A" WHERE A != ?'); $stmt->execute(array('A')); var_dump($stmt->rowCount()); -$dbh->commit(); $stmt = $dbh->prepare('DELETE FROM test_rowcount'); $stmt->execute(); var_dump($stmt->rowCount()); -$dbh->commit(); - unset($stmt); unset($dbh);