mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: add PDO::ATTR_AUTOCOMMIT to getAttribute Fix GH-12767: Fixed to be able to change autocommit mode using setAttribute
This commit is contained in:
commit
dcef7039e8
4 changed files with 219 additions and 1 deletions
4
NEWS
4
NEWS
|
@ -28,6 +28,10 @@ PHP NEWS
|
||||||
. Added workaround for SELinux mprotect execheap issue.
|
. Added workaround for SELinux mprotect execheap issue.
|
||||||
See https://bugzilla.kernel.org/show_bug.cgi?id=218258. (ilutov)
|
See https://bugzilla.kernel.org/show_bug.cgi?id=218258. (ilutov)
|
||||||
|
|
||||||
|
- PDO_ODBC:
|
||||||
|
. Fixed bug GH-12767 (Unable to turn on autocommit mode with setAttribute()).
|
||||||
|
(SakiTakamachi)
|
||||||
|
|
||||||
- PHPDBG:
|
- PHPDBG:
|
||||||
. Fixed bug GH-12962 (Double free of init_file in phpdbg_prompt.c). (nielsdos)
|
. Fixed bug GH-12962 (Double free of init_file in phpdbg_prompt.c). (nielsdos)
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,30 @@ static bool odbc_handle_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
|
||||||
}
|
}
|
||||||
H->assume_utf8 = bval;
|
H->assume_utf8 = bval;
|
||||||
return true;
|
return true;
|
||||||
|
case PDO_ATTR_AUTOCOMMIT:
|
||||||
|
if (!pdo_get_bool_param(&bval, val)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dbh->in_txn) {
|
||||||
|
pdo_raise_impl_error(dbh, NULL, "HY000", "Cannot change autocommit mode while a transaction is already open");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dbh->auto_commit ^ bval) {
|
||||||
|
dbh->auto_commit = bval;
|
||||||
|
RETCODE rc = SQLSetConnectAttr(
|
||||||
|
H->dbc,
|
||||||
|
SQL_ATTR_AUTOCOMMIT,
|
||||||
|
dbh->auto_commit ? (SQLPOINTER) SQL_AUTOCOMMIT_ON : (SQLPOINTER) SQL_AUTOCOMMIT_OFF,
|
||||||
|
SQL_IS_INTEGER
|
||||||
|
);
|
||||||
|
if (rc != SQL_SUCCESS) {
|
||||||
|
pdo_odbc_drv_error(
|
||||||
|
dbh->auto_commit ? "SQLSetConnectAttr AUTOCOMMIT = ON" : "SQLSetConnectAttr AUTOCOMMIT = OFF"
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
strcpy(H->einfo.last_err_msg, "Unknown Attribute");
|
strcpy(H->einfo.last_err_msg, "Unknown Attribute");
|
||||||
H->einfo.what = "setAttribute";
|
H->einfo.what = "setAttribute";
|
||||||
|
@ -386,7 +410,9 @@ static int odbc_handle_get_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
|
||||||
case PDO_ODBC_ATTR_ASSUME_UTF8:
|
case PDO_ODBC_ATTR_ASSUME_UTF8:
|
||||||
ZVAL_BOOL(val, H->assume_utf8 ? 1 : 0);
|
ZVAL_BOOL(val, H->assume_utf8 ? 1 : 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
case PDO_ATTR_AUTOCOMMIT:
|
||||||
|
ZVAL_BOOL(val, dbh->auto_commit);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
53
ext/pdo_odbc/tests/autocommit.phpt
Normal file
53
ext/pdo_odbc/tests/autocommit.phpt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
--TEST--
|
||||||
|
PDO ODBC auto commit mode
|
||||||
|
--EXTENSIONS--
|
||||||
|
pdo_odbc
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require 'ext/pdo/tests/pdo_test.inc';
|
||||||
|
PDOTest::skip();
|
||||||
|
?>
|
||||||
|
--XLEAK--
|
||||||
|
A bug in msodbcsql causes a memory leak when reconnecting after closing. See GH-12306
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require 'ext/pdo/tests/pdo_test.inc';
|
||||||
|
|
||||||
|
$table = 'autocommit_pdo_odbc';
|
||||||
|
|
||||||
|
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||||
|
$db->exec("CREATE TABLE {$table} (id INT, name VARCHAR(255))");
|
||||||
|
unset($db);
|
||||||
|
|
||||||
|
$db = new PDO(getenv('PDOTEST_DSN'), getenv('PDOTEST_USER'), getenv('PDOTEST_PASS'), [
|
||||||
|
PDO::ATTR_AUTOCOMMIT => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
|
||||||
|
$db->query("INSERT INTO {$table} (id, name) VALUES (1, 'test')");
|
||||||
|
unset($db);
|
||||||
|
|
||||||
|
$db = new PDO(getenv('PDOTEST_DSN'), getenv('PDOTEST_USER'), getenv('PDOTEST_PASS'));
|
||||||
|
|
||||||
|
$r = $db->query("SELECT * FROM {$table}");
|
||||||
|
var_dump($r->fetchAll(PDO::FETCH_ASSOC));
|
||||||
|
|
||||||
|
echo "done!";
|
||||||
|
?>
|
||||||
|
--CLEAN--
|
||||||
|
<?php
|
||||||
|
require 'ext/pdo/tests/pdo_test.inc';
|
||||||
|
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||||
|
$db->exec("DROP TABLE IF EXISTS autocommit_pdo_odbc");
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
[0]=>
|
||||||
|
array(2) {
|
||||||
|
["id"]=>
|
||||||
|
string(1) "1"
|
||||||
|
["name"]=>
|
||||||
|
string(4) "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done!
|
135
ext/pdo_odbc/tests/autocommit_change_mode.phpt
Normal file
135
ext/pdo_odbc/tests/autocommit_change_mode.phpt
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
--TEST--
|
||||||
|
PDO ODBC auto commit mode
|
||||||
|
--EXTENSIONS--
|
||||||
|
pdo_odbc
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require 'ext/pdo/tests/pdo_test.inc';
|
||||||
|
PDOTest::skip();
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require 'ext/pdo/tests/pdo_test.inc';
|
||||||
|
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||||
|
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
echo "========== not in transaction ==========\n";
|
||||||
|
|
||||||
|
echo "auto commit ON from ON\n";
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo "Success\n\n";
|
||||||
|
|
||||||
|
echo "auto commit OFF from ON\n";
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo "Success\n\n";
|
||||||
|
|
||||||
|
echo "auto commit OFF from OFF\n";
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo "Success\n\n";
|
||||||
|
|
||||||
|
echo "auto commit ON from OFF\n";
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo "Success\n\n";
|
||||||
|
|
||||||
|
echo "========== in transaction ==========\n";
|
||||||
|
|
||||||
|
echo "begin transaction\n";
|
||||||
|
$db->beginTransaction();
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
echo "auto commit ON from ON, expect error\n";
|
||||||
|
try {
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo $e->getMessage()."\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "auto commit OFF from ON, expect error\n";
|
||||||
|
try {
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo $e->getMessage()."\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "end transaction\n";
|
||||||
|
$db->rollback();
|
||||||
|
|
||||||
|
echo "auto commit OFF\n";
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
|
||||||
|
|
||||||
|
echo "begin transaction\n";
|
||||||
|
$db->beginTransaction();
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
echo "auto commit ON from OFF, expect error\n";
|
||||||
|
try {
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo $e->getMessage()."\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "auto commit OFF from OFF, expect error\n";
|
||||||
|
try {
|
||||||
|
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||||
|
echo $e->getMessage()."\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "end transaction\n";
|
||||||
|
$db->rollback();
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
echo "done!";
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
========== not in transaction ==========
|
||||||
|
auto commit ON from ON
|
||||||
|
bool(true)
|
||||||
|
Success
|
||||||
|
|
||||||
|
auto commit OFF from ON
|
||||||
|
bool(false)
|
||||||
|
Success
|
||||||
|
|
||||||
|
auto commit OFF from OFF
|
||||||
|
bool(false)
|
||||||
|
Success
|
||||||
|
|
||||||
|
auto commit ON from OFF
|
||||||
|
bool(true)
|
||||||
|
Success
|
||||||
|
|
||||||
|
========== in transaction ==========
|
||||||
|
begin transaction
|
||||||
|
|
||||||
|
auto commit ON from ON, expect error
|
||||||
|
bool(true)
|
||||||
|
SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open
|
||||||
|
|
||||||
|
auto commit OFF from ON, expect error
|
||||||
|
bool(true)
|
||||||
|
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
|
||||||
|
bool(false)
|
||||||
|
SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open
|
||||||
|
|
||||||
|
auto commit OFF from OFF, expect error
|
||||||
|
bool(false)
|
||||||
|
SQLSTATE[HY000]: General error: Cannot change autocommit mode while a transaction is already open
|
||||||
|
|
||||||
|
end transaction
|
||||||
|
|
||||||
|
done!
|
Loading…
Add table
Add a link
Reference in a new issue