postgres-notify-send-mode-v1.patch
text/x-patch
Filename: postgres-notify-send-mode-v1.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| contrib/tcn/tcn.c | 1 | 1 |
| doc/src/sgml/ref/notify.sgml | 48 | 15 |
| src/backend/commands/async.c | 58 | 11 |
| src/backend/nodes/copyfuncs.c | 4 | 3 |
| src/backend/nodes/equalfuncs.c | 4 | 3 |
| src/backend/nodes/outfuncs.c | 2 | 1 |
| src/backend/nodes/readfuncs.c | 2 | 1 |
| src/backend/parser/gram.y | 33 | 11 |
| src/backend/tcop/utility.c | 4 | 4 |
| src/backend/utils/adt/ruleutils.c | 3 | 1 |
| src/include/catalog/pg_proc.dat | 4 | 0 |
| src/include/commands/async.h | 7 | 1 |
| src/include/nodes/parsenodes.h | 13 | 5 |
| src/test/regress/expected/async.out | 20 | 0 |
| src/test/regress/sql/async.sql | 9 | 0 |
contrib/tcn/tcn.c | 2 +-
doc/src/sgml/ref/notify.sgml | 63 +++++++++++++++++++++++++--------
src/backend/commands/async.c | 69 +++++++++++++++++++++++++++++++------
src/backend/nodes/copyfuncs.c | 7 ++--
src/backend/nodes/equalfuncs.c | 7 ++--
src/backend/nodes/outfuncs.c | 3 +-
src/backend/nodes/readfuncs.c | 3 +-
src/backend/parser/gram.y | 44 +++++++++++++++++------
src/backend/tcop/utility.c | 8 ++---
src/backend/utils/adt/ruleutils.c | 4 ++-
src/include/catalog/pg_proc.dat | 4 +++
src/include/commands/async.h | 8 ++++-
src/include/nodes/parsenodes.h | 18 +++++++---
src/test/regress/expected/async.out | 20 +++++++++++
src/test/regress/sql/async.sql | 9 +++++
15 files changed, 212 insertions(+), 57 deletions(-)
diff --git a/contrib/tcn/tcn.c b/contrib/tcn/tcn.c
index 5355a64c5e..196e0989a4 100644
--- a/contrib/tcn/tcn.c
+++ b/contrib/tcn/tcn.c
@@ -161,7 +161,7 @@ triggered_change_notification(PG_FUNCTION_ARGS)
strcpy_quoted(payload, SPI_getvalue(trigtuple, tupdesc, colno), '\'');
}
- Async_Notify(channel, payload->data);
+ Async_Notify(channel, payload->data, NOTIFY_SEND_UNIQUE);
}
ReleaseSysCache(indexTuple);
break;
diff --git a/doc/src/sgml/ref/notify.sgml b/doc/src/sgml/ref/notify.sgml
index e0e125a2a2..ad0795fd2d 100644
--- a/doc/src/sgml/ref/notify.sgml
+++ b/doc/src/sgml/ref/notify.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
-NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable class="parameter">payload</replaceable> ]
+NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable class="parameter">payload</replaceable> [ , <replaceable class="parameter">send_mode</replaceable> ] ]
</synopsis>
</refsynopsisdiv>
@@ -47,10 +47,10 @@ NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable cla
</para>
<para>
- The information passed to the client for a notification event includes the
- notification channel
- name, the notifying session's server process <acronym>PID</acronym>, and the
- payload string, which is an empty string if it has not been specified.
+ The information passed to the client for a notification event includes
+ the notification channel name, the notifying session's server process
+ <acronym>PID</acronym>, and the payload string, which is an empty string
+ if it has not been specified.
</para>
<para>
@@ -92,21 +92,13 @@ NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable cla
is that applications using <command>NOTIFY</command> for real-time signaling
should try to keep their transactions short.
</para>
-
<para>
- If the same channel name is signaled multiple times from the same
- transaction with identical payload strings, the
- database server can decide to deliver a single notification only.
- On the other hand, notifications with distinct payload strings will
- always be delivered as distinct notifications. Similarly, notifications from
- different transactions will never get folded into one notification.
Except for dropping later instances of duplicate notifications,
<command>NOTIFY</command> guarantees that notifications from the same
transaction get delivered in the order they were sent. It is also
- guaranteed that messages from different transactions are delivered in
- the order in which the transactions committed.
+ guaranteed that messages from different transactions are delivered
+ in the order in which the transactions committed.
</para>
-
<para>
It is common for a client that executes <command>NOTIFY</command>
to be listening on the same notification channel itself. In that case
@@ -147,6 +139,23 @@ NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable cla
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">send_mode</replaceable></term>
+ <listitem>
+ <para>
+ Controls collapsing of repeated messages. Can be either
+ <literal>'unique'</literal> (the default) or <literal>'all'</literal>.
+
+ When set to <literal>'unique'</literal>, notification will be skipped if
+ the same channel was already signaled with identical payload in the same
+ transaction block (finished with <literal>COMMIT</literal>,
+ <literal>END</literal> or <literal>SAVEPOINT</literal>).
+
+ When set to <literal>'all'</literal>, duplicates will not be collapsed.
+
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -190,6 +199,14 @@ NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable cla
to use than the <command>NOTIFY</command> command if you need to work with
non-constant channel names and payloads.
</para>
+ <para>
+ There is a three-argument version,
+ <literal><function>pg_notify</function>(<type>text</type>,
+ <type>text</type>, <type>text</type>)</literal>. The third argument
+ corresponds to the <replaceable
+ class="parameter">send_mode</replaceable> parameter of the
+ <literal>NOTIFY</literal> command.
+ </para>
</refsect2>
</refsect1>
@@ -210,6 +227,22 @@ Asynchronous notification "virtual" with payload "This is the payload" received
LISTEN foo;
SELECT pg_notify('fo' || 'o', 'pay' || 'load');
Asynchronous notification "foo" with payload "payload" received from server process with PID 14728.
+
+/* Identical messages from same (sub-) transaction will be eliminated,
+ unless you use send_mode = 'all' */
+LISTEN bar;
+BEGIN;
+NOTIFY bar, 'Coffee please';
+NOTIFY bar, 'Coffee please';
+NOTIFY bar, 'Milk please';
+NOTIFY bar, 'Milk please', 'off';
+SAVEPOINT s;
+NOTIFY bar, 'Coffee please';
+COMMIT;
+Asynchronous notification "bar" with payload "Coffee please" received from server process with PID 31517.
+Asynchronous notification "bar" with payload "Milk please" received from server process with PID 31517.
+Asynchronous notification "bar" with payload "Milk please" received from server process with PID 31517.
+Asynchronous notification "bar" with payload "Coffee please" received from server process with PID 31517.
</programlisting></para>
</refsect1>
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 5a7ee0de4c..f953424986 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -49,12 +49,14 @@
* 4. The NOTIFY statement (routine Async_Notify) stores the notification in
* a backend-local list which will not be processed until transaction end.
*
- * Duplicate notifications from the same transaction are sent out as one
- * notification only. This is done to save work when for example a trigger
- * on a 2 million row table fires a notification for each row that has been
- * changed. If the application needs to receive every single notification
- * that has been sent, it can easily add some unique string into the extra
- * payload parameter.
+ * In the default send_mode ('unique'), duplicate notifications from the
+ * same transaction are sent out as one notification only. This is done to
+ * save work when for example a trigger on a 2 million row table fires a
+ * notification for each row that has been changed. If the application needs
+ * to receive every single notification that has been sent, it can easily
+ * add some unique string into the extra payload parameter.
+ *
+ * If send_mode is 'all', de-duplication is not performed.
*
* When the transaction is ready to commit, PreCommit_Notify() adds the
* pending notifications to the head of the queue. The head pointer of the
@@ -523,7 +525,51 @@ pg_notify(PG_FUNCTION_ARGS)
/* For NOTIFY as a statement, this is checked in ProcessUtility */
PreventCommandDuringRecovery("NOTIFY");
- Async_Notify(channel, payload);
+ Async_Notify(channel, payload, true);
+
+ PG_RETURN_VOID();
+}
+
+
+/*
+ * pg_notify_mode
+ * SQL function to send a notification event, 3-argument version
+ */
+Datum
+pg_notify_mode(PG_FUNCTION_ARGS)
+{
+ const char *channel;
+ const char *payload;
+ const char *p_send_mode;
+ NotifySendMode send_mode;
+
+ if (PG_ARGISNULL(0))
+ channel = "";
+ else
+ channel = text_to_cstring(PG_GETARG_TEXT_PP(0));
+
+ if (PG_ARGISNULL(1))
+ payload = "";
+ else
+ payload = text_to_cstring(PG_GETARG_TEXT_PP(1));
+
+ if (PG_ARGISNULL(2))
+ {
+ send_mode = NOTIFY_SEND_UNIQUE;
+ }
+ else
+ {
+ p_send_mode = text_to_cstring(PG_GETARG_TEXT_PP(2));
+ if (strcmp(p_send_mode, "all") == 0)
+ send_mode = NOTIFY_SEND_ALL;
+ else
+ send_mode = NOTIFY_SEND_UNIQUE;
+ }
+
+ /* For NOTIFY as a statement, this is checked in ProcessUtility */
+ PreventCommandDuringRecovery("NOTIFY");
+
+ Async_Notify(channel, payload, send_mode);
PG_RETURN_VOID();
}
@@ -539,7 +585,7 @@ pg_notify(PG_FUNCTION_ARGS)
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*/
void
-Async_Notify(const char *channel, const char *payload)
+Async_Notify(const char *channel, const char *payload, NotifySendMode send_mode)
{
Notification *n;
MemoryContext oldcontext;
@@ -569,9 +615,10 @@ Async_Notify(const char *channel, const char *payload)
errmsg("payload string too long")));
}
- /* no point in making duplicate entries in the list ... */
- if (AsyncExistsPendingNotify(channel, payload))
- return;
+ if (send_mode == NOTIFY_SEND_UNIQUE)
+ /* remove duplicate entries in the list */
+ if (AsyncExistsPendingNotify(channel, payload))
+ return;
/*
* The notification list needs to live until end of transaction, so store
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index a0c1389488..ddefeda8d3 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3622,8 +3622,9 @@ _copyNotifyStmt(const NotifyStmt *from)
{
NotifyStmt *newnode = makeNode(NotifyStmt);
- COPY_STRING_FIELD(conditionname);
+ COPY_STRING_FIELD(channel);
COPY_STRING_FIELD(payload);
+ COPY_SCALAR_FIELD(send_mode);
return newnode;
}
@@ -3633,7 +3634,7 @@ _copyListenStmt(const ListenStmt *from)
{
ListenStmt *newnode = makeNode(ListenStmt);
- COPY_STRING_FIELD(conditionname);
+ COPY_STRING_FIELD(channel);
return newnode;
}
@@ -3643,7 +3644,7 @@ _copyUnlistenStmt(const UnlistenStmt *from)
{
UnlistenStmt *newnode = makeNode(UnlistenStmt);
- COPY_STRING_FIELD(conditionname);
+ COPY_STRING_FIELD(channel);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 3cab90e9f8..1c60b55b94 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1480,8 +1480,9 @@ _equalRuleStmt(const RuleStmt *a, const RuleStmt *b)
static bool
_equalNotifyStmt(const NotifyStmt *a, const NotifyStmt *b)
{
- COMPARE_STRING_FIELD(conditionname);
+ COMPARE_STRING_FIELD(channel);
COMPARE_STRING_FIELD(payload);
+ COMPARE_SCALAR_FIELD(send_mode);
return true;
}
@@ -1489,7 +1490,7 @@ _equalNotifyStmt(const NotifyStmt *a, const NotifyStmt *b)
static bool
_equalListenStmt(const ListenStmt *a, const ListenStmt *b)
{
- COMPARE_STRING_FIELD(conditionname);
+ COMPARE_STRING_FIELD(channel);
return true;
}
@@ -1497,7 +1498,7 @@ _equalListenStmt(const ListenStmt *a, const ListenStmt *b)
static bool
_equalUnlistenStmt(const UnlistenStmt *a, const UnlistenStmt *b)
{
- COMPARE_STRING_FIELD(conditionname);
+ COMPARE_STRING_FIELD(channel);
return true;
}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index d9a5e8cb6a..d228cd51bd 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2660,8 +2660,9 @@ _outNotifyStmt(StringInfo str, const NotifyStmt *node)
{
WRITE_NODE_TYPE("NOTIFY");
- WRITE_STRING_FIELD(conditionname);
+ WRITE_STRING_FIELD(channel);
WRITE_STRING_FIELD(payload);
+ WRITE_ENUM_FIELD(send_mode, NotifySendMode);
}
static void
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 0a34fd9684..a98211da45 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -296,8 +296,9 @@ _readNotifyStmt(void)
{
READ_LOCALS(NotifyStmt);
- READ_STRING_FIELD(conditionname);
+ READ_STRING_FIELD(channel);
READ_STRING_FIELD(payload);
+ READ_ENUM_FIELD(send_mode, NotifySendMode);
READ_DONE();
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 753af6073f..ce44312ac6 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -525,6 +525,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <ival> Iconst SignedIconst
%type <str> Sconst comment_text notify_payload
+%type <boolean> notify_send_mode
%type <str> RoleId opt_boolean_or_string
%type <list> var_list
%type <str> ColId ColLabel var_name type_function_name param_name
@@ -9741,24 +9742,45 @@ opt_instead:
*
*****************************************************************************/
-NotifyStmt: NOTIFY ColId notify_payload
- {
- NotifyStmt *n = makeNode(NotifyStmt);
- n->conditionname = $2;
- n->payload = $3;
- $$ = (Node *)n;
- }
+NotifyStmt:
+ NOTIFY ColId
+ {
+ NotifyStmt *n = makeNode(NotifyStmt);
+ n->channel = $2;
+ n->payload = NULL;
+ n->send_mode = NOTIFY_SEND_UNIQUE;
+ $$ = (Node *)n;
+ }
+ | NOTIFY ColId notify_payload
+ {
+ NotifyStmt *n = makeNode(NotifyStmt);
+ n->channel = $2;
+ n->payload = $3;
+ n->send_mode = NOTIFY_SEND_UNIQUE;
+ $$ = (Node *)n;
+ }
+ | NOTIFY ColId notify_payload notify_send_mode
+ {
+ NotifyStmt *n = makeNode(NotifyStmt);
+ n->channel = $2;
+ n->payload = $3;
+ n->send_mode = $4;
+ $$ = (Node *)n;
+ }
;
notify_payload:
',' Sconst { $$ = $2; }
- | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+notify_send_mode:
+ ',' opt_boolean_or_string { $$ = $2; }
;
ListenStmt: LISTEN ColId
{
ListenStmt *n = makeNode(ListenStmt);
- n->conditionname = $2;
+ n->channel = $2;
$$ = (Node *)n;
}
;
@@ -9767,13 +9789,13 @@ UnlistenStmt:
UNLISTEN ColId
{
UnlistenStmt *n = makeNode(UnlistenStmt);
- n->conditionname = $2;
+ n->channel = $2;
$$ = (Node *)n;
}
| UNLISTEN '*'
{
UnlistenStmt *n = makeNode(UnlistenStmt);
- n->conditionname = NULL;
+ n->channel = NULL;
$$ = (Node *)n;
}
;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 6ec795f1b4..c0fc895535 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -611,7 +611,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
NotifyStmt *stmt = (NotifyStmt *) parsetree;
PreventCommandDuringRecovery("NOTIFY");
- Async_Notify(stmt->conditionname, stmt->payload);
+ Async_Notify(stmt->channel, stmt->payload, stmt->send_mode);
}
break;
@@ -621,7 +621,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
PreventCommandDuringRecovery("LISTEN");
CheckRestrictedOperation("LISTEN");
- Async_Listen(stmt->conditionname);
+ Async_Listen(stmt->channel);
}
break;
@@ -631,8 +631,8 @@ standard_ProcessUtility(PlannedStmt *pstmt,
/* we allow UNLISTEN during recovery, as it's a noop */
CheckRestrictedOperation("UNLISTEN");
- if (stmt->conditionname)
- Async_Unlisten(stmt->conditionname);
+ if (stmt->channel)
+ Async_Unlisten(stmt->channel);
else
Async_UnlistenAll();
}
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 85055bbb95..c4b83c50f3 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -6581,11 +6581,13 @@ get_utility_query_def(Query *query, deparse_context *context)
appendContextKeyword(context, "",
0, PRETTYINDENT_STD, 1);
appendStringInfo(buf, "NOTIFY %s",
- quote_identifier(stmt->conditionname));
+ quote_identifier(stmt->channel));
if (stmt->payload)
{
appendStringInfoString(buf, ", ");
simple_quote_literal(buf, stmt->payload);
+ appendStringInfo(buf, ", '%s'",
+ (stmt->send_mode == NOTIFY_SEND_ALL ? "all" : "unique"));
}
}
else
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 2e9d6cf2f5..6d38bbcfc0 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7549,6 +7549,10 @@
proname => 'pg_notify', proisstrict => 'f', provolatile => 'v',
proparallel => 'r', prorettype => 'void', proargtypes => 'text text',
prosrc => 'pg_notify' },
+{ oid => '3998', descr => 'send a notification event',
+ proname => 'pg_notify', proisstrict => 'f', provolatile => 'v',
+ proparallel => 'r', prorettype => 'void', proargtypes => 'text text text',
+ prosrc => 'pg_notify_mode' },
{ oid => '3296',
descr => 'get the fraction of the asynchronous notification queue currently in use',
proname => 'pg_notification_queue_usage', provolatile => 'v',
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index cfea78e039..1154f3c281 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -22,6 +22,12 @@
*/
#define NUM_ASYNC_BUFFERS 8
+typedef enum NotifySendMode
+{
+ NOTIFY_SEND_UNIQUE,
+ NOTIFY_SEND_ALL
+} NotifySendMode;
+
extern bool Trace_notify;
extern volatile sig_atomic_t notifyInterruptPending;
@@ -33,7 +39,7 @@ extern void NotifyMyFrontEnd(const char *channel,
int32 srcPid);
/* notify-related SQL statements */
-extern void Async_Notify(const char *channel, const char *payload);
+extern void Async_Notify(const char *channel, const char *payload, NotifySendMode send_mode);
extern void Async_Listen(const char *channel);
extern void Async_Unlisten(const char *channel);
extern void Async_UnlistenAll(void);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index fe35783359..e669b76b39 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -27,6 +27,7 @@
#include "nodes/primnodes.h"
#include "nodes/value.h"
#include "partitioning/partdefs.h"
+#include "commands/async.h"
typedef enum OverridingKind
@@ -2944,12 +2945,19 @@ typedef struct RuleStmt
/* ----------------------
* Notify Statement
* ----------------------
+typedef enum NotifySendMode
+{
+ NOTIFY_SEND_UNIQUE,
+ NOTIFY_SEND_ALL
+} NotifySendMode;
*/
+
typedef struct NotifyStmt
{
- NodeTag type;
- char *conditionname; /* condition name to notify */
- char *payload; /* the payload string, or NULL if none */
+ NodeTag type;
+ char *channel; /* channel name to notify */
+ char *payload; /* the payload string, or NULL if none */
+ NotifySendMode send_mode; /* Send mode */
} NotifyStmt;
/* ----------------------
@@ -2959,7 +2967,7 @@ typedef struct NotifyStmt
typedef struct ListenStmt
{
NodeTag type;
- char *conditionname; /* condition name to listen on */
+ char *channel; /* channel name to listen on */
} ListenStmt;
/* ----------------------
@@ -2969,7 +2977,7 @@ typedef struct ListenStmt
typedef struct UnlistenStmt
{
NodeTag type;
- char *conditionname; /* name to unlisten on, or NULL for all */
+ char *channel; /* channel name to unlisten, or NULL for all */
} UnlistenStmt;
/* ----------------------
diff --git a/src/test/regress/expected/async.out b/src/test/regress/expected/async.out
index 19cbe38e63..7555d0bcc2 100644
--- a/src/test/regress/expected/async.out
+++ b/src/test/regress/expected/async.out
@@ -8,6 +8,18 @@ SELECT pg_notify('notify_async1','sample message1');
(1 row)
+SELECT pg_notify('notify_async1','sample_message1','unique');
+ pg_notify
+-----------
+
+(1 row)
+
+SELECT pg_notify('notify_async1','sample_message1','all');
+ pg_notify
+-----------
+
+(1 row)
+
SELECT pg_notify('notify_async1','');
pg_notify
-----------
@@ -27,8 +39,16 @@ SELECT pg_notify(NULL,'sample message1');
ERROR: channel name cannot be empty
SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1');
ERROR: channel name too long
+-- Should fail. Invalid 3rd parameter
+NOTIFY notify_async2, 'test', 'invalid';
+ERROR: ?
+NOTIFY notify_async2, 'test', true;
+ERROR: ?
--Should work. Valid NOTIFY/LISTEN/UNLISTEN commands
NOTIFY notify_async2;
+NOTIFY notify_async2, '';
+NOTIFY notify_async2, '', 'unique';
+NOTIFY notify_async2, '', 'all';
LISTEN notify_async2;
UNLISTEN notify_async2;
UNLISTEN *;
diff --git a/src/test/regress/sql/async.sql b/src/test/regress/sql/async.sql
index 40f6e01538..ad349cce37 100644
--- a/src/test/regress/sql/async.sql
+++ b/src/test/regress/sql/async.sql
@@ -4,6 +4,8 @@
--Should work. Send a valid message via a valid channel name
SELECT pg_notify('notify_async1','sample message1');
+SELECT pg_notify('notify_async1','sample_message1','unique');
+SELECT pg_notify('notify_async1','sample_message1','all');
SELECT pg_notify('notify_async1','');
SELECT pg_notify('notify_async1',NULL);
@@ -12,8 +14,15 @@ SELECT pg_notify('','sample message1');
SELECT pg_notify(NULL,'sample message1');
SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1');
+-- Should fail. Invalid 3rd parameter
+NOTIFY notify_async2, 'test', 'invalid';
+NOTIFY notify_async2, 'test', true;
+
--Should work. Valid NOTIFY/LISTEN/UNLISTEN commands
NOTIFY notify_async2;
+NOTIFY notify_async2, '';
+NOTIFY notify_async2, '', 'unique';
+NOTIFY notify_async2, '', 'all';
LISTEN notify_async2;
UNLISTEN notify_async2;
UNLISTEN *;