php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36469 pg_get_result does not block
Submitted: 2006-02-21 08:18 UTC Modified: 2008-11-10 01:00 UTC
Votes:5
Avg. Score:3.6 ± 0.8
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:1 (33.3%)
From: levi at alliancesoftware dot com dot au Assigned: helly (profile)
Status: No Feedback Package: PostgreSQL related
PHP Version: 5.1.2 OS: FC3
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: levi at alliancesoftware dot com dot au
New email:
PHP Version: OS:

 

 [2006-02-21 08:18 UTC] levi at alliancesoftware dot com dot au
Description:
------------
According to the pg_connection_busy documentation, if pg_get_result is called on a pg_send_query that is currently executing, it should block until results become available.

Occasionally this does not happen if the query had an error in it.

Reproduce code:
---------------
#!/usr/local/bin/php51
<?php
  $connStr = sprintf("host=%s dbname=%s user=%s password=%s", 'localhost', 'testdb', 'liam', 'liam');
  $dbconn = pg_connect($connStr) or die("Could not connect");

        $i = 0;

        while (!pg_connection_busy($dbconn)) {
                pg_send_query($dbconn, 'i am a syntax error');
                pg_get_result($dbconn);
                $i++;
        }

        echo "got a busy signal after $i commands";

?>


Expected result:
----------------
(Loops forever)

Actual result:
--------------
got a busy signal after 221 commands

(actual count varies, but always returns within 1 second. Approximately 1/3 of the time it gives a "happy" run and will loop forever)


Note that if the SQL statement was a valid statement, I cannot get the erroneous behaviour to occur.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-02-22 10:57 UTC] tony2001@php.net
What PG version are you using and did you try to upgrade it (and rebuild PHP with the upgraded libs) ?
 [2006-02-23 02:35 UTC] levi at alliancesoftware dot com dot au
I have tried and can repeat the error on the following:

Fedora Core 2 (x86):
 PHP 5.0.4* PG 8.1*
 PHP 5.1.2* PG 8.1*

Fedora Core 3 (x86-64):
 PHP 5.0.4** PG 8.1*
 PHP 5.1.2*  PG 8.1*

* = compiled from source
** = system RPM

 I also doublechecked that the connection only says its busy if the previous query had an error (ie change the query to a valid SELECT and it doesn't happen)
 [2008-11-02 12:31 UTC] jani@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2008-11-10 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-11-09 00:43 UTC] levi at alliancesoftware dot com dot au
Edit: We gave up on Postgres for that project, but had to revisit this recently; the issue still exists but it seems the cause is actually that pg_connection_busy() stays true for some time after a query that causes any sort of postgres error.

Tested additionally with
x86_64/FC10 + PHP [5.2.9 | 5.2.11 | 5.3.0] + Postgres 8.3


#!/usr/bin/php
<?php
    $connStr = sprintf("host=%s dbname=%s user=%s password=%s", 'localhost', 'testlevi', 'levi', 'levi');
    ($dbConn = pg_connect($connStr)) or die("Could not connect");

    @pg_query($dbConn, "drop table thisTableExists");
    @pg_query($dbConn, "drop table thisTableDoesNotExist");
    pg_query($dbConn, "create table thisTableExists (x varchar(255))") || die("Can't create table");
    pg_query($dbConn, "insert into thisTableExists values ('foo')") || die("Can't insert first row");
    pg_query($dbConn, "insert into thisTableExists values ('foo2')") || die("Can't insert second row");

    $loopCount = 0;
    while (true) {

            // First 20 queries are completely valid; after that we try invalid queries

            $sql = ($loopCount < 20)
                ? "select * from thisTableExists; select * from thisTableExists;"
                : "select * from thisTableExists; select * from thisTableDoesNotExist;";

            // Issue the queries
            pg_send_query($dbConn, $sql);

            // Check first result
            $result1 = pg_get_result($dbConn);
            $rowCount1 = pg_num_rows($result1);
            if ($rowCount1 != 2) die("Bad result set returned (1)");

            // Check the second result
            $result2 = pg_get_result($dbConn);
            $rowCount2 = pg_num_rows($result2);
            $expectedRowCount = ($loopCount >= 20) ? 0 : 2;
            if ($rowCount2 != $expectedRowCount) die("Bad result set returned (2)");

            if (pg_connection_busy($dbConn)) {
                echo (pg_connection_status($dbConn) == PGSQL_CONNECTION_OK) ? '+' : '-';
                while (pg_connection_busy($dbConn)) {
                    echo '!';
                    usleep(1);
                }
            }
            echo ".";
            $loopCount++;
    }
?>

Expected output:
........................... etc
Actual output:
....................+!.+!.+...............+.+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.....+!.+!.+!.+



Comments for anyone else experiencing this:

It seems pg_get_result() correctly waits until results are ready, but even after pg_get_result() returns, if there was an error in the query then pg_connection_busy() will stay true for some time.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Mar 31 12:01:28 2025 UTC