php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63365 pg_send_query() blocks on queries to other connections.
Submitted: 2012-10-25 20:58 UTC Modified: 2013-06-05 19:41 UTC
From: chris at ctgameinfo dot com Assigned:
Status: Not a bug Package: PostgreSQL related
PHP Version: 5.4.8 OS: FreeBSD (probably irrevelant)
Private report: No CVE-ID: None
 [2012-10-25 20:58 UTC] chris at ctgameinfo dot com
Description:
------------
If I open a connection and send a long running query with pg_send_query, then 
open a second connection and try to send a query over the second connection with 
pg_send_query it will block on the first connection's query not being complete

Test script:
---------------
<?php
for($i=1;$i<=10;$i++)
{
	echo "Interation $i\n";

	$dbconn = pg_connect("user=pgsql dbname=postgres", PGSQL_CONNECT_FORCE_NEW);

        // Will block in the second loop interation
	pg_send_query($dbconn, "select pg_sleep(5);");
}
?>

Expected result:
----------------
pg_send_query should only block on incomplete queries on the same connection.

Actual result:
--------------
pg_send_query blocks on incomplete queries on any connection.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-10-28 13:57 UTC] felipe@php.net
-Status: Open +Status: Feedback
 [2012-10-28 13:57 UTC] felipe@php.net
Please, check out the return from pg_last_error($dbconn); after the pg_send_query() call and post the result in there.
 [2012-10-28 16:24 UTC] chris at ctgameinfo dot com
-Status: Feedback +Status: Open
 [2012-10-28 16:24 UTC] chris at ctgameinfo dot com
Modified test script with requested pg_last_error output. 
-------
<?php
for($i=1;$i<=10;$i++)
{
	echo "Interation $i\n";

	$dbconn = pg_connect("user=cstdenis dbname=postgres", 
PGSQL_CONNECT_FORCE_NEW);

        // Will block in the second loop interation
	pg_send_query($dbconn, "select pg_sleep(5);");
	echo "Last error: '".pg_last_error($dbconn)."'\n";
}
?>

Output:
-------
Interation 1
Last error: ''
Interation 2
Last error: ''
Interation 3
Last error: ''
Interation 4
Last error: ''
Interation 5
Last error: ''
Interation 6
Last error: ''
Interation 7
Last error: ''
Interation 8
Last error: ''
Interation 9
Last error: ''
Interation 10
Last error: ''
 [2013-06-05 13:48 UTC] mbeccati@php.net
This won't block:

<?php

for($i=1;$i<=10;$i++)
{
        echo "Interation $i\n";

        $dbconn[$i] = pg_connect("dbname=postgres", PGSQL_CONNECT_FORCE_NEW);

        // Will block in the second loop interation
        pg_send_query($dbconn[$i], "select pg_sleep(5)");
        echo "Last error: '".pg_last_error($dbconn[$i])."'\n";
}

?>

So the issue only happens when you "overwrite" an existing connection
 [2013-06-05 13:52 UTC] mbeccati@php.net
-Status: Open +Status: Not a bug
 [2013-06-05 13:52 UTC] mbeccati@php.net
Sorry, hit submit too early. By overwriting the connection variable, you force the old connection to be closed. In order to do that, PHP is waiting for the query to complete and discard its output.
 [2013-06-05 19:41 UTC] chris at ctgameinfo dot com
It should be able to throw away the variable without closing the connection 
(much 
like calling pg_connect without assigning to a variable leaves it open). I 
realize doing this could cause a memory leak for the duration of the script, but 
as long as the implicit close at script termination still happens it should be 
fine.

In any case, please update the documentation to make this more clear since 
blocking on variable assignment is not something one normally expects to happen.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 11:01:30 2024 UTC