Greg Sabino Mullane <g...@endpoint.com> writes: > I came across some unusual behavior with listen. Basically, if you > unlisten and listen inside of a transaction, new notices are not > picked up right away - but they will show up if you send yourself > a notice. It also works as expected if you unlisten, commit, and > then re-listen. Tested on 9.1 and 9.2. Demo psql script:
Huh. If you run this in an assert-enabled build, it gets an assert failure: regression=# listen abc; LISTEN regression=# notify abc; NOTIFY Asynchronous notification "abc" received from server process with PID 19048. regression=# begin; unlisten *; listen abc; commit; BEGIN UNLISTEN LISTEN COMMIT regression=# notify abc; The connection to the server was lost. Attempting reset: Failed. The Assert is TRAP: FailedAssertion("!(MyProcPid == (asyncQueueControl->backend[MyBackendId].pid))", File: "async.c", Line: 1821) which shows that we aren't actually registered in the global array of listeners, even though we think we should be. I think the problem is that we do Exec_ListenPreCommit, then Exec_UnlistenAllCommit, then Exec_ListenCommit --- and the second of these undoes our registration as a listener. That needs rethinking. Looking at it, the backendHasExecutedInitialListen flag seems pretty badly thought out too. It looks to me like we'd be better off with a flag defined like "amRegisteredListener" that tracks whether we're currently in the array or not, and during AtCommit_Notify() we shouldn't deregister as a listener until we've scanned all the pending actions and know whether we are ending in a no-listens state or not. regards, tom lane -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs