-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Tom Lane wrote:
> Joe Conway <m...@joeconway.com> writes:
>> Sure, I guess I ought to use the latest-and-greatest. Any other comments
>> before I commit?
> 
> That "be_pid/be_pid" hack in the regression test is pretty ugly, and
> doesn't test anything very useful anyway seeing that it's integer
> division.  Could you do something like
>       be_pid = pg_backend_pid() AS is_self_notify
> instead, to verify that it's a self-notify?  (This is not quite right
> because you'd need to execute pg_backend_pid() at the remote end, but
> I'm not awake enough to remember the dblink syntax for that.  Maybe
> it's too complex to be worth it, but I think demonstrating how to
> check for self-notify would be a useful bit of doco.)
> 
> Otherwise it looks ok to me.

OK, still not pretty, but at least more useful. Last call for
comments...I hope ;-)

Joe
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iQIcBAEBCAAGBQJKePNeAAoJEDfy90M199hlduYP/2UaEuEXzWnGS1RX4Be+UajS
LBrS5uanAEUJcohnpMXCHjZVuLJBhXl8r/2RPXsVt5Fem3oYkxFrK3eCysMZs0jJ
F6iWb/Hiyi3bVf8coHjeabm0j/TF5yYsKuE3D0kcxktwKjq9vyGOxkadcAXV/lq1
+awVp5tip1ko3R20zSv+N4dcZp6ewHZ9Fa9AT9BS/3D5vQn6Jq3aUajqZ1DdSw0W
Fm5DlAl632xB8dQ9G/nNUYXMf5040OyD7foZEncS30i+diyHEvx5++5peCmlAvBj
KmeULbsmGn+brlQjvMftJU5LnOzEkKAHYs90BjR/jHoivJHSBjDNbREm1lJqGU9q
DU7E3NXz2/hva+/a+PPoyZjJDj+wvxzBivySB/fPCLpQFATDYHQ+1iMOKWqiGO1q
N1I6bEEZTAH1/8drANR224/BVnOs10s+4uUL5L8Me+eWO0gIxyhpHyIg/MkhlJ1a
Aopz3p7XEuXWmo4XGEAMVhJ2NpBiNKc69Ihno3kkY6FMo4Hs8rNsP+bdZnpBhugO
JB0+EDhSaVf2O7a8zmz3fylP2cNBQTh3gZlbNzYlnYgkhkuTXda2JXjwdnAkd5DK
33vVaJ0swb7MzeBWzP5PDMXKbzVPtz7FvReVVhIZbAJk+oVlwlw+KMRo8z8g0ci8
CgX2i1YwCh0AGuk450rZ
=JQmH
-----END PGP SIGNATURE-----
Index: contrib/dblink/dblink.c
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/dblink.c,v
retrieving revision 1.82
diff -c -r1.82 dblink.c
*** contrib/dblink/dblink.c	11 Jun 2009 14:48:50 -0000	1.82
--- contrib/dblink/dblink.c	4 Aug 2009 13:41:26 -0000
***************
*** 1635,1640 ****
--- 1635,1723 ----
  	PG_RETURN_DATUM(current_query(fcinfo));
  }
  
+ /*
+  * Retrieve async notifications for a connection. 
+  *
+  * Returns an setof record of notifications, or an empty set if none recieved.
+  * Can optionally take a named connection as parameter, but uses the unnamed connection per default.
+  *
+  */
+ #define DBLINK_NOTIFY_COLS		3
+ 
+ PG_FUNCTION_INFO_V1(dblink_get_notify);
+ Datum
+ dblink_get_notify(PG_FUNCTION_ARGS)
+ {
+ 	PGconn			   *conn = NULL;
+ 	remoteConn		   *rconn = NULL;
+ 	PGnotify		   *notify;
+ 	ReturnSetInfo	   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
+ 	TupleDesc			tupdesc;
+ 	Tuplestorestate	   *tupstore;
+ 	MemoryContext		per_query_ctx;
+ 	MemoryContext		oldcontext;
+ 
+ 	DBLINK_INIT;
+ 	if (PG_NARGS() == 1)
+ 		DBLINK_GET_NAMED_CONN;
+ 	else
+ 		conn = pconn->conn;
+ 
+ 	/* create the tuplestore */
+ 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
+ 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
+ 
+ 	tupdesc = CreateTemplateTupleDesc(DBLINK_NOTIFY_COLS, false);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "notify_name",
+ 					   TEXTOID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "be_pid",
+ 					   INT4OID, -1, 0);
+ 	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "extra",
+ 					   TEXTOID, -1, 0);
+ 
+ 	tupstore = tuplestore_begin_heap(true, false, work_mem);
+ 	rsinfo->returnMode = SFRM_Materialize;
+ 	rsinfo->setResult = tupstore;
+ 	rsinfo->setDesc = tupdesc;
+ 
+ 	MemoryContextSwitchTo(oldcontext);
+ 
+ 	PQconsumeInput(conn);
+ 	while ((notify = PQnotifies(conn)) != NULL)
+ 	{
+ 		Datum		values[DBLINK_NOTIFY_COLS];
+ 		bool		nulls[DBLINK_NOTIFY_COLS];
+ 
+ 		memset(values, 0, sizeof(values));
+ 		memset(nulls, 0, sizeof(nulls));
+ 
+ 		if (notify->relname != NULL)
+ 			values[0] = CStringGetTextDatum(notify->relname);
+ 		else
+ 			nulls[0] = true;
+ 
+ 		values[1] = Int32GetDatum(notify->be_pid);
+ 
+ 		if (notify->extra != NULL)
+ 			values[2] = CStringGetTextDatum(notify->extra);
+ 		else
+ 			nulls[2] = true;
+ 
+ 		/* switch to appropriate context while storing the tuple */
+ 		MemoryContextSwitchTo(per_query_ctx);
+ 		tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+ 		MemoryContextSwitchTo(oldcontext);
+ 
+ 		PQfreemem(notify);
+ 		PQconsumeInput(conn);
+ 	}
+ 
+ 	/* clean up and return the tuplestore */
+ 	tuplestore_donestoring(tupstore);
+ 
+ 	return (Datum) 0;
+ }
+ 
  /*************************************************************
   * internal functions
   */
Index: contrib/dblink/dblink.h
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/dblink.h,v
retrieving revision 1.22
diff -c -r1.22 dblink.h
*** contrib/dblink/dblink.h	9 Jun 2009 17:41:02 -0000	1.22
--- contrib/dblink/dblink.h	4 Aug 2009 13:41:26 -0000
***************
*** 57,61 ****
--- 57,62 ----
  extern Datum dblink_build_sql_delete(PG_FUNCTION_ARGS);
  extern Datum dblink_build_sql_update(PG_FUNCTION_ARGS);
  extern Datum dblink_current_query(PG_FUNCTION_ARGS);
+ extern Datum dblink_get_notify(PG_FUNCTION_ARGS);
  
  #endif   /* DBLINK_H */
Index: contrib/dblink/dblink.sql.in
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/dblink.sql.in,v
retrieving revision 1.18
diff -c -r1.18 dblink.sql.in
*** contrib/dblink/dblink.sql.in	9 Jun 2009 17:41:02 -0000	1.18
--- contrib/dblink/dblink.sql.in	4 Aug 2009 13:44:34 -0000
***************
*** 202,204 ****
--- 202,223 ----
  RETURNS text
  AS 'MODULE_PATHNAME', 'dblink_error_message'
  LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION dblink_get_notify(
+     OUT notify_name TEXT,
+     OUT be_pid INT4,
+     OUT extra TEXT
+ ) 
+ RETURNS setof record
+ AS 'MODULE_PATHNAME', 'dblink_get_notify'
+ LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION dblink_get_notify(
+     conname TEXT,
+     OUT notify_name TEXT,
+     OUT be_pid INT4,
+     OUT extra TEXT
+ ) 
+ RETURNS setof record
+ AS 'MODULE_PATHNAME', 'dblink_get_notify'
+ LANGUAGE C STRICT;
Index: contrib/dblink/uninstall_dblink.sql
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/uninstall_dblink.sql,v
retrieving revision 1.7
diff -c -r1.7 uninstall_dblink.sql
*** contrib/dblink/uninstall_dblink.sql	5 Apr 2008 02:26:14 -0000	1.7
--- contrib/dblink/uninstall_dblink.sql	4 Aug 2009 13:41:26 -0000
***************
*** 76,78 ****
--- 76,82 ----
  DROP FUNCTION dblink_is_busy(text);
  
  DROP FUNCTION dblink_send_query(text, text);
+ 
+ DROP FUNCTION dblink_get_notify();
+ 
+ DROP FUNCTION dblink_get_notify(text);
Index: contrib/dblink/expected/dblink.out
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/expected/dblink.out,v
retrieving revision 1.25
diff -c -r1.25 dblink.out
*** contrib/dblink/expected/dblink.out	6 Jun 2009 21:27:56 -0000	1.25
--- contrib/dblink/expected/dblink.out	5 Aug 2009 02:37:51 -0000
***************
*** 827,829 ****
--- 827,880 ----
  DROP USER MAPPING FOR public SERVER fdtest;
  DROP SERVER fdtest;
  DROP FOREIGN DATA WRAPPER postgresql;
+ -- test asynchronous notifications
+ SELECT dblink_connect('dbname=contrib_regression');
+  dblink_connect
+ ----------------
+  OK
+ (1 row)
+ 
+ --should return listen
+ SELECT dblink_exec('LISTEN regression');
+  dblink_exec
+ -------------
+  LISTEN
+ (1 row)
+ 
+ --should return listen
+ SELECT dblink_exec('LISTEN foobar');
+  dblink_exec
+ -------------
+  LISTEN
+ (1 row)
+ 
+ SELECT dblink_exec('NOTIFY regression');
+  dblink_exec
+ -------------
+  NOTIFY
+ (1 row)
+ 
+ SELECT dblink_exec('NOTIFY foobar');
+  dblink_exec
+ -------------
+  NOTIFY
+ (1 row)
+ 
+ SELECT notify_name, be_pid = (select t.be_pid from dblink('select pg_backend_pid()') as t(be_pid int)) AS is_self_notify, extra from dblink_get_notify();
+  notify_name | is_self_notify | extra
+ -------------+----------------+-------
+  regression  | t              |
+  foobar      | t              |
+ (2 rows)
+ 
+ SELECT * from dblink_get_notify();
+  notify_name | be_pid | extra
+ -------------+--------+-------
+ (0 rows)
+ 
+ SELECT dblink_disconnect();
+  dblink_disconnect
+ -------------------
+  OK
+ (1 row)
+ 
Index: contrib/dblink/sql/dblink.sql
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/sql/dblink.sql,v
retrieving revision 1.21
diff -c -r1.21 dblink.sql
*** contrib/dblink/sql/dblink.sql	6 Jun 2009 21:27:56 -0000	1.21
--- contrib/dblink/sql/dblink.sql	5 Aug 2009 02:36:00 -0000
***************
*** 389,391 ****
--- 389,408 ----
  DROP USER MAPPING FOR public SERVER fdtest;
  DROP SERVER fdtest;
  DROP FOREIGN DATA WRAPPER postgresql;
+ 
+ -- test asynchronous notifications
+ SELECT dblink_connect('dbname=contrib_regression');
+ 
+ --should return listen
+ SELECT dblink_exec('LISTEN regression');
+ --should return listen
+ SELECT dblink_exec('LISTEN foobar');
+ 
+ SELECT dblink_exec('NOTIFY regression');
+ SELECT dblink_exec('NOTIFY foobar');
+ 
+ SELECT notify_name, be_pid = (select t.be_pid from dblink('select pg_backend_pid()') as t(be_pid int)) AS is_self_notify, extra from dblink_get_notify();
+ 
+ SELECT * from dblink_get_notify();
+ 
+ SELECT dblink_disconnect();
Index: doc/src/sgml/dblink.sgml
===================================================================
RCS file: /opt/src/cvs/pgsql/doc/src/sgml/dblink.sgml,v
retrieving revision 1.8
diff -c -r1.8 dblink.sgml
*** doc/src/sgml/dblink.sgml	18 Jun 2009 14:34:36 -0000	1.8
--- doc/src/sgml/dblink.sgml	4 Aug 2009 13:41:26 -0000
***************
*** 1260,1265 ****
--- 1260,1338 ----
    </refsect1>
   </refentry>
  
+  <refentry id="CONTRIB-DBLINK-GET-NOTIFY">
+   <refnamediv>
+    <refname>dblink_get_notify</refname>
+    <refpurpose>retrieve async notifications on a connection</refpurpose>
+   </refnamediv>
+ 
+   <refsynopsisdiv>
+    <synopsis>
+     dblink_get_notify() returns setof (notify_name text, be_pid int, extra text)
+     dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text)
+    </synopsis>
+   </refsynopsisdiv>
+ 
+   <refsect1>
+    <title>Description</title>
+ 
+    <para>
+     <function>dblink_get_notify</> retrieves notifications on either 
+     the unnamed connection, or on a named connection if specified.
+     To receive notifications via dblink, <function>LISTEN</> must 
+     first be issued, using <function>dblink_exec</>.
+     For details see <xref linkend="sql-listen"> and <xref linkend="sql-notify">.
+    </para>
+ 
+   </refsect1>
+ 
+   <refsect1>
+    <title>Arguments</title>
+ 
+    <variablelist>
+     <varlistentry>
+      <term><parameter>conname</parameter></term>
+      <listitem>
+       <para>
+        The name of a named connection to get notifications on.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </refsect1>
+ 
+   <refsect1>
+    <title>Return Value</title>
+     <para>Returns setof (notify_name text, be_pid int, extra text), or an empty set if none.</para>
+   </refsect1>
+ 
+   <refsect1>
+    <title>Example</title>
+ 
+    <programlisting>
+ test=# SELECT dblink_exec('LISTEN virtual');
+  dblink_exec 
+ -------------
+  LISTEN
+ (1 row)
+ 
+ test=# SELECT * FROM dblink_get_notify();
+  notify_name | be_pid | extra
+ -------------+--------+-------
+ (0 rows)
+ 
+ test=# NOTIFY virtual;
+ NOTIFY
+ 
+ SELECT * FROM dblink_get_notify();
+  notify_name | be_pid | extra
+ -------------+--------+-------
+  virtual     |   1229 |
+ (1 row)
+    </programlisting>
+   </refsect1>
+  </refentry>
+ 
   <refentry id="CONTRIB-DBLINK-GET-RESULT">
    <refmeta>
     <refentrytitle>dblink_get_result</refentrytitle>
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to