- MySQLi:
. Fixed bug #79375 (mysqli_store_result does not report error from lock wait
timeout). (Kamil Tekiela, Nikita)
+ . Fixed bug #76525 (mysqli::commit does not throw if MYSQLI_REPORT_ERROR
+ enabled and mysqlnd used). (Kamil Tekiela)
+
+- PDO MySQL:
+ . Fixed bug #66528 (No PDOException or errorCode if database becomes
+ unavailable before PDO::commit). (Nikita)
29 Oct 2020, PHP 7.4.12
}
fail:
- if (attr == PDO_ATTR_AUTOCOMMIT) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0, "The auto-commit mode cannot be changed for this driver");
- } else if (!dbh->methods->set_attribute) {
+ if (!dbh->methods->set_attribute) {
pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support setting attributes");
} else {
PDO_HANDLE_DBH_ERR();
{
PDO_DBG_ENTER("mysql_handle_commit");
PDO_DBG_INF_FMT("dbh=%p", dbh);
- PDO_DBG_RETURN(0 == mysql_commit(((pdo_mysql_db_handle *)dbh->driver_data)->server));
+ if (mysql_commit(((pdo_mysql_db_handle *)dbh->driver_data)->server)) {
+ pdo_mysql_error(dbh);
+ PDO_DBG_RETURN(0);
+ }
+ PDO_DBG_RETURN(1);
}
/* }}} */
{
PDO_DBG_ENTER("mysql_handle_rollback");
PDO_DBG_INF_FMT("dbh=%p", dbh);
- PDO_DBG_RETURN(0 <= mysql_rollback(((pdo_mysql_db_handle *)dbh->driver_data)->server));
+ if (mysql_rollback(((pdo_mysql_db_handle *)dbh->driver_data)->server)) {
+ pdo_mysql_error(dbh);
+ PDO_DBG_RETURN(0);
+ }
+ PDO_DBG_RETURN(1);
}
/* }}} */
PDO_DBG_ENTER("mysql_handle_autocommit");
PDO_DBG_INF_FMT("dbh=%p", dbh);
PDO_DBG_INF_FMT("dbh->autocommit=%d", dbh->auto_commit);
- PDO_DBG_RETURN(0 <= mysql_autocommit(((pdo_mysql_db_handle *)dbh->driver_data)->server, dbh->auto_commit));
+ if (mysql_autocommit(((pdo_mysql_db_handle *)dbh->driver_data)->server, dbh->auto_commit)) {
+ pdo_mysql_error(dbh);
+ PDO_DBG_RETURN(0);
+ }
+ PDO_DBG_RETURN(1);
}
/* }}} */
/* ignore if the new value equals the old one */
if (dbh->auto_commit ^ bval) {
dbh->auto_commit = bval;
- mysql_handle_autocommit(dbh);
+ if (!mysql_handle_autocommit(dbh)) {
+ PDO_DBG_RETURN(0);
+ }
}
PDO_DBG_RETURN(1);
--- /dev/null
+--TEST--
+Bug #66528: No PDOException or errorCode if database becomes unavailable before PDO::commit
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+MySQLPDOTest::skip();
+?>
+--FILE--
+<?php
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+
+$dbh = MySQLPDOTest::factory();
+$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
+
+$dbh->exec('DROP TABLE IF EXISTS test');
+$dbh->exec('CREATE TABLE test (a int) engine=innodb');
+$dbh->beginTransaction();
+$dbh->exec('INSERT INTO test (a) VALUES (1), (2)');
+$stmt = $dbh->query('SELECT * FROM test');
+
+try {
+ $dbh->commit();
+} catch (PDOException $e) {
+ echo $e->getMessage(), "\n";
+}
+
+try {
+ $dbh->rollBack();
+} catch (PDOException $e) {
+ echo $e->getMessage(), "\n";
+}
+
+try {
+ $dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
+} catch (PDOException $e) {
+ echo $e->getMessage(), "\n";
+}
+
+?>
+--CLEAN--
+<?php
+require __DIR__ . '/mysql_pdo_test.inc';
+MySQLPDOTest::dropTestTable();
+?>
+--EXPECT--
+SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
+SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
+SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.