Workaround for a bug in unixODBC 2.3.4 (#334)
* Adding a workaround for the error handling issue with unixODBC 2.3.4 when conneciton pooling is enabled * Adding a check to apply the workaround only to PDO SQLSRV * Update core_util.cpp * Unix Conn Pool test * Modifying the test to use autonomous_setup.php * Updating path to isPooled.php
This commit is contained in:
parent
6bd361c1ef
commit
6809f0f7ea
|
@ -247,6 +247,17 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
|||
r = SQLGetDiagRecW( h_type, h, record_number, wsqlstate, &error->native_code, wnative_message,
|
||||
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
||||
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
||||
// Workaround for a bug in unixODBC 2.3.4 when connection pooling is enabled (PDO SQLSRV).
|
||||
// Instead of returning false, we return an empty error message to prevent the driver from throwing an exception.
|
||||
// To reproduce:
|
||||
// Create a connection and close it (return it to the pool)
|
||||
// Create a new connection from the pool.
|
||||
// Prepare and execute a statement that generates an info message (such as 'USE tempdb;')
|
||||
#ifdef __APPLE__
|
||||
if( r == SQL_NO_DATA && ctx.driver() != NULL /*PDO SQLSRV*/ ) {
|
||||
r = SQL_SUCCESS;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
if( !SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) {
|
||||
return false;
|
||||
}
|
||||
|
|
34
test/pdo_sqlsrv/PDO_ConnPool_Unix.phpt
Normal file
34
test/pdo_sqlsrv/PDO_ConnPool_Unix.phpt
Normal file
|
@ -0,0 +1,34 @@
|
|||
--TEST--
|
||||
PDO Connection Pooling Test on Unix
|
||||
This test assumes odbcinst.ini has not been modified.
|
||||
This test also requires root privileges to modify odbcinst.ini file on Linux.
|
||||
--SKIPIF--
|
||||
<?php if(PHP_OS === "WINNT") die("Skipped: Test for Linux and Mac");
|
||||
--FILE--
|
||||
<?php
|
||||
$lines_to_add="CPTimeout=5\n[ODBC]\nPooling=Yes\n";
|
||||
|
||||
//get odbcinst.ini location
|
||||
$lines = explode("\n", shell_exec("odbcinst -j"));
|
||||
$odbcinst_ini = explode(" ", $lines[1])[1];
|
||||
|
||||
//enable pooling by modifying the odbcinst.ini file
|
||||
$current = file_get_contents($odbcinst_ini);
|
||||
$current.=$lines_to_add;
|
||||
file_put_contents($odbcinst_ini, $current);
|
||||
|
||||
//Creating a new php process, because for changes in odbcinst.ini file to affect pooling, drivers must be reloaded.
|
||||
print_r(shell_exec("php ./test/pdo_sqlsrv/isPooled.php"));
|
||||
|
||||
//disable pooling by modifying the odbcinst.ini file
|
||||
$current = file_get_contents($odbcinst_ini);
|
||||
$current = str_replace("CPTimeout=5\n[ODBC]\nPooling=Yes\n",'',$current);
|
||||
file_put_contents($odbcinst_ini, $current);
|
||||
|
||||
print_r(shell_exec("php ./test/pdo_sqlsrv/isPooled.php"));
|
||||
?>
|
||||
--EXPECT--
|
||||
Pooled
|
||||
Not Pooled
|
||||
|
||||
|
25
test/pdo_sqlsrv/isPooled.php
Normal file
25
test/pdo_sqlsrv/isPooled.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
include_once 'autonomous_setup.php';
|
||||
$conn1 = new PDO("sqlsrv:Server=$serverName", $username, $password);
|
||||
$connId1 = ConnectionID($conn1);
|
||||
$conn1 = null;
|
||||
|
||||
$conn2 = new PDO("sqlsrv:Server=$serverName", $username, $password);
|
||||
$connId2 = ConnectionID($conn2);
|
||||
|
||||
if ($connId1 === $connId2){
|
||||
echo "Pooled\n";
|
||||
}else{
|
||||
echo "Not Pooled\n";
|
||||
}
|
||||
|
||||
function ConnectionID($conn)
|
||||
{
|
||||
$tsql = "SELECT [connection_id] FROM [sys].[dm_exec_connections] where session_id = @@SPID";
|
||||
$stmt = $conn->query($tsql);
|
||||
$connID = $stmt->fetchColumn(0);
|
||||
$stmt->closeCursor();
|
||||
$stmt = null;
|
||||
return ($connID);
|
||||
}
|
||||
?>
|
Loading…
Reference in a new issue