From:
Operating system: all
PHP version: Irrelevant
Package: PostgreSQL related
Bug Type: Bug
Bug description:pg_affected_rows inconsistent behavior (depends on PostgreSQL
server version)
Description:
------------
According to the manual, pg_affected_rows should returns "the number of
tuples
(instances/records/rows) affected by INSERT, UPDATE, and DELETE queries.".
The
manual details : "The number of rows affected by the query. If no tuple is
affected, it will return 0.".
PHP pg_affected_rows uses libpq's PQcmdTuples() to implement this:
PHP_FUNCTION(pg_affected_rows)
{
php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_CMD_TUPLES);
}
static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int
entry_type)
{
[...]
case PHP_PG_CMD_TUPLES:
Z_LVAL_P(return_value) = atoi(PQcmdTuples(pgsql_result));
But server's answers to PQcmdTuples() commands changed since PostgreSQL
9.0.
When executed after a SELECT, PostgreSQL < 9.0 returned 0 (as in "0 rows
were
affected"); starting with PostgreSQL 9.0, the server returns the number of
SELECTed rows.
See how the PQcmdTuples documentation was updated after pg 9:
http://www.postgresql.org/docs/8.4/interactive/libpq-exec.html#LIBPQ-EXEC-
SELECT-INFO
http://www.postgresql.org/docs/9.1/interactive/libpq-exec.html#LIBPQ-EXEC-
SELECT-INFO
PostgreSQL C API doesn't actually offers a "tell me how many rows were
written/modified" function. But we can restore the previous
pg_affected_rows
behavior, and enjoy consistent results no matter which server version we
run
against, by unconditionally returning 0 after a SELECT.
This is what the attached patch does, identifying the SELECT with
PQresultStatus() value (which returns PGRES_COMMAND_OK after a successful
DML,
as opposed to PGRES_TUPLES_OK after a SELECT, etc).
If you ask so, I can also provide an alternative patch (which tests the
string
returned by PQcmdStatus(), a bit ugly imo) and/or an unit test script for
PHP's
test framework.
Test script:
---------------
// Bug on a PostgreSQL >= 9.0 server, ok on older versions.
$dbh = pg_pconnect("dbname=postgres host=localhost user=postgres
port=5432");
$q = pg_query($dbh, "SELECT * from generate_series(1, 42);");
var_dump(pg_affected_rows($q));
Expected result:
----------------
int(0)
Actual result:
--------------
int(42)
--
Edit bug report at https://bugs.php.net/bug.php?id=61266&edit=1
--
Try a snapshot (PHP 5.4):
https://bugs.php.net/fix.php?id=61266&r=trysnapshot54
Try a snapshot (PHP 5.3):
https://bugs.php.net/fix.php?id=61266&r=trysnapshot53
Try a snapshot (trunk):
https://bugs.php.net/fix.php?id=61266&r=trysnapshottrunk
Fixed in SVN:
https://bugs.php.net/fix.php?id=61266&r=fixed
Fixed in SVN and need be documented:
https://bugs.php.net/fix.php?id=61266&r=needdocs
Fixed in release:
https://bugs.php.net/fix.php?id=61266&r=alreadyfixed
Need backtrace:
https://bugs.php.net/fix.php?id=61266&r=needtrace
Need Reproduce Script:
https://bugs.php.net/fix.php?id=61266&r=needscript
Try newer version:
https://bugs.php.net/fix.php?id=61266&r=oldversion
Not developer issue:
https://bugs.php.net/fix.php?id=61266&r=support
Expected behavior:
https://bugs.php.net/fix.php?id=61266&r=notwrong
Not enough info:
https://bugs.php.net/fix.php?id=61266&r=notenoughinfo
Submitted twice:
https://bugs.php.net/fix.php?id=61266&r=submittedtwice
register_globals:
https://bugs.php.net/fix.php?id=61266&r=globals
PHP 4 support discontinued:
https://bugs.php.net/fix.php?id=61266&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=61266&r=dst
IIS Stability:
https://bugs.php.net/fix.php?id=61266&r=isapi
Install GNU Sed:
https://bugs.php.net/fix.php?id=61266&r=gnused
Floating point limitations:
https://bugs.php.net/fix.php?id=61266&r=float
No Zend Extensions:
https://bugs.php.net/fix.php?id=61266&r=nozend
MySQL Configuration Error:
https://bugs.php.net/fix.php?id=61266&r=mysqlcfg