implementing NOTIFY with message parameter - Mailing list pgsql-hackers

From Andras Kadinger
Subject implementing NOTIFY with message parameter
Date
Msg-id Pine.LNX.4.44.0505120800280.21939-200000@ns.surfnonstop.com
Whole thread Raw
Responses Re: implementing NOTIFY with message parameter
List pgsql-hackers
Greetings everyone,

Beginner in PostgreSQL internals, seeking the insight of more experienced.

" (At present, the extra field is unused and will always point to an empty 
string.)" - http://www.postgresql.org/docs/8.0/static/libpq-notify.html
regarding PGnotify returned by PQnotifies

I would like to implement the functionality that is the idea behind that
extra message field: I would like to be able to give NOTIFY an extra 
string parameter, and I would like that string to end up in that extra 
field of that PGnotify structure above.

I have been using PostgreSQL for different projects in the last 5-6 years,
but have never looked under the hood until now. Please guide me.

Pointers to previous relevant discussions would also be kindly welcomed.

----------------

Command/syntax:

Being unfamiliar with flex/yacc/bison, I chose the simplest route, and 
added an optional Sconst:

opt_notifymessage:                       Sconst  { $$ = $1; }                       | /*EMPTY*/     { $$ = ""; }

----------------

Storage:

In this scenario, we need to store the message with each notification, so
notifications would no longer be conceptually unique(relname), but
unique(relname,message) instead. As a result, they will need a separate
table. I therefore invented pg_notify:

pg_notify:       NameData        relname;       int4            senderpid;       int4            recipientpid;
NameData       message; //FIXME: what about type text instead?
 

and as senderpid now has a place in pg_notify, I removed it from
pg_listener:

pg_listener:       NameData        relname;       int4            listenerpid;

----------------

backend/commands/async.c:

Async_Notify - now takes NotifyStmt * as input

AtCommit_Notify - scans pg_listener, and for each tuple that has pending                 notifies for its relname,
insertsa tuple into pg_notify
 

ProcessIncomingNotify - now scans pg_notify instead of pg_listener,                        delivers notifies sent to
thatBE PID,                       and deletes their tuples
 

NotifyMyFrontend - now has got a new parameter, char *message, that it                  sends to the frontend

----------------

Issues:

I don't know much about string internals in PostgreSQL, so I just
duplicated code for the string type already used in pg_listener: NameData;  
but NameData is limited to NAMEDATALEN bytes (64 currently) and for
certain applications this might be a limiting factor. It would be nice to
have something longer - say NOTIFYMESSAGELEN = 256 bytes? I guess it would
be easy to come up with another, size-limited string type, but then again
256 - nevertheless sufficient for my current application, where 64
wouldn't do - is just another arbitrary number, and as such, hard to
objectively reason for or against.

Is text/bpchar/varlena (with its TOASTedness) viable here and for this
purpose? Its capacity would certainly waive that concern.

I am also not very proficient in char* and NameData semantics, storage
issues and accessors - please scrutinize the code in this respect as well.

My modifications leave behavior of LISTEN/NOTIFY mostly unchanged, 
but they change the structure and behavior of pg_listener. Should we worry 
about this and try to add code to emulate the old behavior?

-----------------

I attached a - never compiled, never tested - patch, as a vehicle to
demonstrate my ideas, solicit further discussion and ask for guidance.

Thank you in advance.

Best Regards,
Andras

pgsql-hackers by date:

Previous
From: Josh Berkus
Date:
Subject: Re: New Contrib Build?
Next
From: "Dave Page"
Date:
Subject: Re: Server instrumentation for 8.1