Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LISTEN/NOTIFY using pg_notify(text, text) in PostgreSQL

Tags:

I have been playing with PostgreSQL's notification system and cannot for the life of my figure out why pg_notify(text, text) never works. This feature is not overly documented and I cannot find many examples of it being used in the wild so I figured nobody would mind me asking here.

Running the following works exactly as expected:

LISTEN my_channel;  NOTIFY my_channel, 'my message text'; 

Using the pg_notify() function however returns a null value and no notification is ever sent. No error is given either. An example of the use is:

SELECT pg_notify('my_channel', 'my message text'); 

I could use the NOTIFY function however my goal is to streamline the notification into a query like so:

select pg_notify(get_player_error_channel(username)::TEXT, 'test'::TEXT)     from player; 

I assume I must be missing something ridiculous but I have had zero luck figuring out the reason for this. The page discussing NOTIFY can be found here: http://www.postgresql.org/docs/9.0/static/sql-notify.html

On it, it mentions this about pg_notify(), which makes me assume there would be nothing drastically different.

pg_notify To send a notification you can also use the function pg_notify(text, text). The function takes the channel name as the first argument and the payload as the second. The function is much easier to use than the NOTIFY command if you need to work with non-constant channel names and payloads.

Thanks as always for the assistance

Edit: Database version is: "PostgreSQL 9.0.3 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.2.4, 32-bit"

like image 899
Abstrct Avatar asked Mar 02 '11 20:03

Abstrct


People also ask

What is Postgres listen notify?

The NOTIFY command sends a notification event together with an optional “payload” string to each client application that has previously executed LISTEN channel for the specified channel name in the current database. Notifications are visible to all users.

How to set alert in PostgreSQL?

In the Azure portal, select the Azure Database for PostgreSQL server you want to monitor. Select Add metric alert (+ icon). Within the Condition section, select Add condition. Select a metric from the list of signals to be alerted on.

What is Tg_op in PostgreSQL?

TG_OP. Data type text ; a string of INSERT , UPDATE , DELETE , or TRUNCATE telling for which operation the trigger was fired. TG_RELID. Data type oid ; the object ID of the table that caused the trigger invocation. TG_RELNAME.

How do I use triggers in PostgreSQL?

Syntax. CREATE TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name ON table_name [ -- Trigger logic goes here.... ]; Here, event_name could be INSERT, DELETE, UPDATE, and TRUNCATE database operation on the mentioned table table_name. You can optionally specify FOR EACH ROW after table name.


1 Answers

I have discussed this on the PostgreSQL mailing list (http://archives.postgresql.org/pgsql-bugs/2011-03/msg00041.php) and was informed on the reasoning for the behavior.

Their answer is that "..you have to double quote relnames (listen "Test"). if you want the server not to case fold them. pg_notify takes a string, not a relname, which uses different rules." (Thanks Merlin and Tom)

This means that the following works because the channel is always forced to lower case

LISTEN ERRORCHANNEL;  NOTIFY ERRORCHANNEL, 'something!'; NOTIFY eRrorChanNel, 'something!'; 

If you were to add double quotes around the channel name, the case would be maintained.

So, with the following, you would receive the first notification but not the second:

LISTEN "ERRORCHANNEL";  NOTIFY "ERRORCHANNEL", 'something!';  NOTIFY "eRrorChanNel", 'something!'; 

Similarly, the following will work because the double quotes force the case of ERRORCHANNEL to be maintained:

LISTEN "ERRORCHANNEL";  SELECT pg_notify('ERRORCHANNEL', 'something!'); 

While this will not work:

LISTEN ERRORCHANNEL;  SELECT pg_notify('ERRORCHANNEL', 'something!'); 

In this situation ERRORCHANNEL is not in double quotes in the LISTEN command so PostgreSQL forces it to lower case. The channel parameter is of type text rather then relname so the case is left untouched in the pg_notify() function. Together the channels do not match (ERRORCHANNE != errorchannel) so the notification is never received.

like image 110
Abstrct Avatar answered Sep 22 '22 14:09

Abstrct