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,
|
r = SQLGetDiagRecW( h_type, h, record_number, wsqlstate, &error->native_code, wnative_message,
|
||||||
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
||||||
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
// 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 ) {
|
if( !SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) {
|
||||||
return false;
|
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