|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #78621 pgsqlSetNoticeCallback
Submitted: 2019-10-02 05:04 UTC Modified: -
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: guillaume-php at outters dot eu Assigned:
Status: Open Package: PDO PgSQL
PHP Version: 7.3.10 OS: all
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2019-10-02 05:04 UTC] guillaume-php at outters dot eu
There is currently no way to receive PostgreSQL's notices PHP-side.

A PQsetNoticeProcessor has been defined 15 years ago to the empty function _pdo_pgsql_notice, to prevent libpq's default behaviour (fprintfing to stderr)).

Passing notices to PHP could prove useful, allowing e.g. user-defined RAISE NOTICE in PL/pgSQL long-running code to provide feedback.

A user-space callback would give more control on what to do with the message (compared to the exec-then-fetch method of non-PDO pgsql driver's pg_last_notice)… not the least being the live feedback ability.

Test script:
function disp($message) { echo trim($message)."\n"; }
$db = new PDO('pgsql:host=localhost;port=5432;dbname=…', '', '');
if(method_exists($db, 'pgsqlSetNoticeCallback'))
$db->exec("create temporary table t (a varchar(3))");
$db->exec("create function hey() returns trigger as \$\$ begin new.a := 'oh'; raise notice 'I tampered your data, did you know?'; return new; end; \$\$ language plpgsql");
$db->exec("create trigger hop before insert on t for each row execute procedure hey()");
$db->exec("insert into t values ('ah')");
print_r($db->query("select * from t")->fetchAll());

Expected result:
I would like to know that a trigger triggered ("I tampered your data, did you know?").

Actual result:
Only tcpdump will display my carefully-crafted RAISE NOTICE. 


pgsqlSetNoticeCallback.7.diff (last revision 2019-10-02 05:05 UTC by guillaume-php at outters dot eu)

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-02 05:05 UTC] guillaume-php at outters dot eu
The following patch has been added/updated:

Patch Name: pgsqlSetNoticeCallback.7.diff
Revision:   1569992718
 [2019-10-13 23:17 UTC] guillaume-php at outters dot eu
The following pull request has been associated:

Patch Name: pgsqlSetNoticeCallback
On GitHub:
 [2019-12-04 06:21 UTC] guillaume-php at outters dot eu
Note: I considered adding the PDO itself as a first parameter to the callback.

I don't see a usage for it now *; but who knows… Not me, but I would be open to anyone commenting this point of design: now would be the right time to add a first parameter if you think it could be a good idea (with the usual warnings in the user doc: "you get the parameter, but don't dare doing nasty things with it, you'll be on your own to deal with it").

If no comment, I'll stick with the simple, user-side solution exposed here, that is, to get a calling context, do pass an object method to pgsqlSetNoticeCallback and hold your context in that object.

* Conjecture: someone needing to act on the statement upon receiving a notice, e.g. aborting it?
Objection: wouldn't it raise reentrancy issues? And by the way, what is the "current" statement when we have two, not entirely fetched statements? I'm not even sure we can retrieve it from the notice (the notice being emitted at the connection level, not at the statement level).
Conjecture: use it as a discriminant in the callback to know for which DB we get the notice?
Objection: the callback can be an object method, and the object can hold the calling context.
Conjecture: to be consistent with notice callbacks on other drivers?
Objection: I did not see any other implementation…
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 28 15:01:23 2020 UTC