diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 75d0e9d4a0940314b498cc62e6ddaab9acbbc42d..03e5a4ca0468ebed29d02016a04d7e0bbae2c324 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.37 1998/08/19 02:01:39 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.38 1998/08/30 21:04:43 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,29 +34,7 @@
  * -- jw, 12/28/93
  *
  */
-/*
- * The following is the old model which does not work.
- */
-/*
- * Model is:
- * 1. Multiple backends on same machine.
- *
- * 2. Query on one backend sends stuff over an asynchronous portal by
- *	  appending to a relation, and then doing an async. notification
- *	  (which takes place after commit) to all listeners on this relation.
- *
- * 3. Async. notification results in all backends listening on relation
- *	  to be woken up, by a process signal kill(SIGUSR2), with name of relation
- *	  passed in shared memory.
- *
- * 4. Each backend notifies its respective frontend over the comm
- *	  channel using the out-of-band channel.
- *
- * 5. Each frontend receives this notification and processes accordingly.
- *
- * #4,#5 are changing soon with pending rewrite of portal/protocol.
- *
- */
+
 #include <unistd.h>
 #include <signal.h>
 #include <string.h>
@@ -82,17 +60,28 @@
 #include "tcop/dest.h"
 #include "utils/mcxt.h"
 #include "utils/syscache.h"
+#include <utils/trace.h>
+#include <utils/ps_status.h>
+
+#define NotifyUnlock pg_options[OPT_NOTIFYUNLOCK]
+#define NotifyHack   pg_options[OPT_NOTIFYHACK]
+
+extern TransactionState CurrentTransactionState;
+extern CommandDest 		whereToSendOutput;
+
+GlobalMemory notifyContext = NULL;
 
 static int	notifyFrontEndPending = 0;
 static int	notifyIssued = 0;
 static Dllist *pendingNotifies = NULL;
 
-
 static int	AsyncExistsPendingNotify(char *);
 static void ClearPendingNotify(void);
 static void Async_NotifyFrontEnd(void);
+static void Async_NotifyFrontEnd_Aux(void);
 void		Async_Unlisten(char *relname, int pid);
 static void Async_UnlistenOnExit(int code, char *relname);
+static void Async_UnlistenAll(void);
 
 /*
  *--------------------------------------------------------------
@@ -116,33 +105,36 @@ static void Async_UnlistenOnExit(int code, char *relname);
 void
 Async_NotifyHandler(SIGNAL_ARGS)
 {
-	extern TransactionState CurrentTransactionState;
+	TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler");
 
 	if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
 		(CurrentTransactionState->blockState == TRANS_DEFAULT))
 	{
-
-#ifdef ASYNC_DEBUG
-		elog(DEBUG, "Waking up sleeping backend process");
-#endif
+		TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler: "
+				"waking up sleeping backend process");
+		PS_SET_STATUS("async_notify");
 		Async_NotifyFrontEnd();
-
+		PS_SET_STATUS("idle");
 	}
 	else
 	{
-#ifdef ASYNC_DEBUG
-		elog(DEBUG, "Process is in the middle of another transaction, state = %d, block state = %d",
-			 CurrentTransactionState->state,
-			 CurrentTransactionState->blockState);
-#endif
+		TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler: "
+				"process in middle of transaction, state=%d, blockstate=%d",
+				CurrentTransactionState->state,
+				CurrentTransactionState->blockState);
 		notifyFrontEndPending = 1;
+		TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler: notify frontend pending");
 	}
+
+	TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler: done");
 }
 
 /*
  *--------------------------------------------------------------
  * Async_Notify --
  *
+ *		This is executed by the SQL notify command.
+ *
  *		Adds the relation to the list of pending notifies.
  *		All notification happens at end of commit.
  *		^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -151,7 +143,6 @@ Async_NotifyHandler(SIGNAL_ARGS)
  *		then each backend notifies its corresponding front end at
  *		the end of commit.
  *
- *		This correspond to 'notify <relname>' command
  *		-- jw, 12/28/93
  *
  * Results:
@@ -180,9 +171,7 @@ Async_Notify(char *relname)
 
 	char	   *notifyName;
 
-#ifdef ASYNC_DEBUG
-	elog(DEBUG, "Async_Notify: %s", relname);
-#endif
+	TPRINTF(TRACE_NOTIFY, "Async_Notify: %s", relname);
 
 	if (!pendingNotifies)
 		pendingNotifies = DLNewList();
@@ -217,18 +206,32 @@ Async_Notify(char *relname)
 		{
 			rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
 			heap_replace(lRel, &lTuple->t_ctid, rTuple);
+			/* notify is really issued only if a tuple has been changed */
+			notifyIssued = 1;
 		}
 	}
 	heap_endscan(sRel);
-	RelationUnsetLockForWrite(lRel);
+
+	/*
+	 * Note: if the write lock is unset we can get multiple tuples
+	 * with same oid if other backends notify the same relation.
+	 * Use this option at your own risk.
+	 */
+	if (NotifyUnlock) {
+		RelationUnsetLockForWrite(lRel);
+	}
+
 	heap_close(lRel);
-	notifyIssued = 1;
+
+	TPRINTF(TRACE_NOTIFY, "Async_Notify: done %s", relname);
 }
 
 /*
  *--------------------------------------------------------------
  * Async_NotifyAtCommit --
  *
+ *		This is called at transaction commit.
+ *
  *		Signal our corresponding frontend process on relations that
  *		were notified.	Signal all other backend process that
  *		are listening also.
@@ -265,14 +268,12 @@ Async_NotifyAtCommit()
 	if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
 		(CurrentTransactionState->blockState == TRANS_DEFAULT))
 	{
-
 		if (notifyIssued)
-		{						/* 'notify <relname>' issued by us */
+		{
+			/* 'notify <relname>' issued by us */
 			notifyIssued = 0;
 			StartTransactionCommand();
-#ifdef ASYNC_DEBUG
-			elog(DEBUG, "Async_NotifyAtCommit.");
-#endif
+			TPRINTF(TRACE_NOTIFY, "Async_NotifyAtCommit");
 			ScanKeyEntryInitialize(&key, 0,
 								   Anum_pg_listener_notify,
 								   F_INT4EQ,
@@ -294,16 +295,15 @@ Async_NotifyAtCommit()
 
 					if (MyProcPid == DatumGetInt32(d))
 					{
-#ifdef ASYNC_DEBUG
-						elog(DEBUG, "Notifying self, setting notifyFronEndPending to 1");
-#endif
 						notifyFrontEndPending = 1;
+						TPRINTF(TRACE_NOTIFY,
+								"Async_NotifyAtCommit: notifying self");
 					}
 					else
 					{
-#ifdef ASYNC_DEBUG
-						elog(DEBUG, "Notifying others");
-#endif
+						TPRINTF(TRACE_NOTIFY,
+								"Async_NotifyAtCommit: notifying pid %d",
+								DatumGetInt32(d));
 #ifdef HAVE_KILL
 						if (kill(DatumGetInt32(d), SIGUSR2) < 0)
 						{
@@ -315,19 +315,35 @@ Async_NotifyAtCommit()
 				}
 			}
 			heap_endscan(sRel);
-			RelationUnsetLockForWrite(lRel);
 			heap_close(lRel);
 
+			/*
+			 * Notify the frontend inside the current transaction while
+			 * we still have a valid write lock on pg_listeners. This
+			 * avoid waiting until all other backends have finished
+			 * with pg_listener.
+			 */
+			if (notifyFrontEndPending) {
+				/* The aux version is called inside transaction */
+				Async_NotifyFrontEnd_Aux();
+			}
+
+			TPRINTF(TRACE_NOTIFY, "Async_NotifyAtCommit: done");
 			CommitTransactionCommand();
-			ClearPendingNotify();
 		}
-
-		if (notifyFrontEndPending)
-		{						/* we need to notify the frontend of all
-								 * pending notifies. */
-			notifyFrontEndPending = 1;
-			Async_NotifyFrontEnd();
+		else
+		{
+			/*
+			 * No notifies issued by us. If notifyFrontEndPending has been set
+			 * by Async_NotifyHandler notify the frontend of pending notifies
+			 * from other backends.
+			 */
+			if (notifyFrontEndPending) {
+				Async_NotifyFrontEnd();
+			}
 		}
+
+		ClearPendingNotify();
 	}
 }
 
@@ -335,6 +351,8 @@ Async_NotifyAtCommit()
  *--------------------------------------------------------------
  * Async_NotifyAtAbort --
  *
+ *		This is called at transaction commit.
+ *
  *		Gets rid of pending notifies.  List elements are automatically
  *		freed through memory context.
  *
@@ -350,20 +368,19 @@ Async_NotifyAtCommit()
 void
 Async_NotifyAtAbort()
 {
-	extern TransactionState CurrentTransactionState;
-
-	if (notifyIssued)
+	if (pendingNotifies) {
 		ClearPendingNotify();
-	notifyIssued = 0;
-	if (pendingNotifies)
 		DLFreeList(pendingNotifies);
+	}
 	pendingNotifies = DLNewList();
+	notifyIssued = 0;
 
 	if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
 		(CurrentTransactionState->blockState == TRANS_DEFAULT))
 	{
+		/* don't forget to notify front end */
 		if (notifyFrontEndPending)
-		{						/* don't forget to notify front end */
+		{
 			Async_NotifyFrontEnd();
 		}
 	}
@@ -373,11 +390,11 @@ Async_NotifyAtAbort()
  *--------------------------------------------------------------
  * Async_Listen --
  *
+ *		This is executed by the SQL listen command.
+ *
  *		Register a backend (identified by its Unix PID) as listening
  *		on the specified relation.
  *
- *		This corresponds to the 'listen <relation>' command in SQL
- *
  *		One listener per relation, pg_listener relation is keyed
  *		on (relname,pid) to provide multiple listeners in future.
  *
@@ -406,9 +423,13 @@ Async_Listen(char *relname, int pid)
 	char	   *relnamei;
 	TupleDesc	tupDesc;
 
-#ifdef ASYNC_DEBUG
-	elog(DEBUG, "Async_Listen: %s", relname);
-#endif
+	if (whereToSendOutput != Remote) {
+		elog(NOTICE, "Async_Listen: "
+			 "listen not available on interactive sessions");
+		return;
+	}
+
+	TPRINTF(TRACE_NOTIFY, "Async_Listen: %s", relname);
 	for (i = 0; i < Natts_pg_listener; i++)
 	{
 		nulls[i] = ' ';
@@ -438,6 +459,10 @@ Async_Listen(char *relname, int pid)
 			if (pid == MyProcPid)
 				alreadyListener = 1;
 		}
+		if (alreadyListener) {
+			/* No need to scan the rest of the table */
+			break;
+		}
 	}
 	heap_endscan(scan);
 
@@ -445,15 +470,14 @@ Async_Listen(char *relname, int pid)
 	{
 		elog(NOTICE, "Async_Listen: We are already listening on %s",
 			 relname);
+		RelationUnsetLockForWrite(lDesc);
+		heap_close(lDesc);
 		return;
 	}
 
 	tupDesc = lDesc->rd_att;
-	newtup = heap_formtuple(tupDesc,
-						 values,
-						 nulls);
+	newtup = heap_formtuple(tupDesc, values, nulls);
 	heap_insert(lDesc, newtup);
-
 	pfree(newtup);
 
 	/*
@@ -477,12 +501,11 @@ Async_Listen(char *relname, int pid)
  *--------------------------------------------------------------
  * Async_Unlisten --
  *
+ *		This is executed by the SQL unlisten command.
+ *
  *		Remove the backend from the list of listening backends
  *		for the specified relation.
  *
- *		This would correspond to the 'unlisten <relation>'
- *		command, but there isn't one yet.
- *
  * Results:
  *		pg_listeners is updated.
  *
@@ -497,20 +520,81 @@ Async_Unlisten(char *relname, int pid)
 	Relation	lDesc;
 	HeapTuple	lTuple;
 
-	lTuple = SearchSysCacheTuple(LISTENREL,
-								 PointerGetDatum(relname),
+	/* Handle specially the `unlisten "*"' command */
+	if ((!relname) || (*relname == '\0') || (strcmp(relname,"*")==0)) {
+		Async_UnlistenAll();
+		return;
+	}
+
+	TPRINTF(TRACE_NOTIFY, "Async_Unlisten %s", relname);
+
+	lTuple = SearchSysCacheTuple(LISTENREL, PointerGetDatum(relname),
 								 Int32GetDatum(pid),
 								 0, 0);
-	lDesc = heap_openr(ListenerRelationName);
-	RelationSetLockForWrite(lDesc);
-
 	if (lTuple != NULL)
+	{
+		lDesc = heap_openr(ListenerRelationName);
+		RelationSetLockForWrite(lDesc);
 		heap_delete(lDesc, &lTuple->t_ctid);
-
-	RelationUnsetLockForWrite(lDesc);
-	heap_close(lDesc);
+		RelationUnsetLockForWrite(lDesc);
+		heap_close(lDesc);
+	}
 }
 
+/*
+ *--------------------------------------------------------------
+ * Async_UnlistenAll --
+ *
+ *		Unlisten all relations for this backend.
+ *
+ * Results:
+ *		pg_listeners is updated.
+ *
+ * Side effects:
+ *		XXX
+ *
+ *--------------------------------------------------------------
+ */
+static void
+Async_UnlistenAll()
+{
+	HeapTuple	lTuple;
+	Relation	lRel;
+	HeapScanDesc sRel;
+	TupleDesc	tdesc;
+	ScanKeyData key[1];
+
+	TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll");
+	ScanKeyEntryInitialize(&key[0], 0,
+						   Anum_pg_listener_pid,
+						   F_INT4EQ,
+						   Int32GetDatum(MyProcPid));
+	lRel = heap_openr(ListenerRelationName);
+	RelationSetLockForWrite(lRel);
+	tdesc = RelationGetTupleDescriptor(lRel);
+	sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
+
+	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
+	{
+		heap_delete(lRel, &lTuple->t_ctid);
+	}
+	heap_endscan(sRel);
+	RelationUnsetLockForWrite(lRel);
+	heap_close(lRel);
+	TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll: done");
+}
+  
+/*
+ * --------------------------------------------------------------
+ * Async_UnlistenOnExit --
+ *
+ *		This is called at backend exit for each registered listen.
+ *
+ * Results:
+ *		XXX
+ *
+ * --------------------------------------------------------------
+ */
 static void
 Async_UnlistenOnExit(int code,	/* from exitpg */
 					 char *relname)
@@ -522,6 +606,25 @@ Async_UnlistenOnExit(int code,	/* from exitpg */
  * --------------------------------------------------------------
  * Async_NotifyFrontEnd --
  *
+ *		This is called outside transactions. The real work is done
+ *		by Async_NotifyFrontEnd_Aux().
+ *
+ * --------------------------------------------------------------
+ */
+static void
+Async_NotifyFrontEnd()
+{
+	StartTransactionCommand();
+	Async_NotifyFrontEnd_Aux();
+	CommitTransactionCommand();
+}
+
+/*
+ * --------------------------------------------------------------
+ * Async_NotifyFrontEnd_Aux --
+ *
+ *		This must be called inside a transaction block.
+ *
  *		Perform an asynchronous notification to front end over
  *		portal comm channel.  The name of the relation which contains the
  *		data is sent to the front end.
@@ -534,12 +637,9 @@ Async_UnlistenOnExit(int code,	/* from exitpg */
  *
  * --------------------------------------------------------------
  */
-GlobalMemory notifyContext = NULL;
-
 static void
-Async_NotifyFrontEnd()
+Async_NotifyFrontEnd_Aux()
 {
-	extern CommandDest whereToSendOutput;
 	HeapTuple	lTuple,
 				rTuple;
 	Relation	lRel;
@@ -552,12 +652,15 @@ Async_NotifyFrontEnd()
 				nulls[3];
 	bool		isnull;
 
-	notifyFrontEndPending = 0;
+#define MAX_DONE 64
 
-#ifdef ASYNC_DEBUG
-	elog(DEBUG, "Async_NotifyFrontEnd: notifying front end.");
-#endif
+	char		*done[MAX_DONE];
+	int			ndone = 0;
+	int			i;
+
+	notifyFrontEndPending = 0;
 
+	TPRINTF(TRACE_NOTIFY, "Async_NotifyFrontEnd");
 	StartTransactionCommand();
 	ScanKeyEntryInitialize(&key[0], 0,
 						   Anum_pg_listener_notify,
@@ -580,11 +683,35 @@ Async_NotifyFrontEnd()
 
 	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
 	{
-		d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull);
+		d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc,
+						 &isnull);
+
+		/*
+		 * This hack deletes duplicate tuples which can be left
+		 * in the table if the NotifyUnlock option is set.
+		 * I'm further investigating this.	-- dz
+		 */
+		if (NotifyHack) {
+			for (i=0; i<ndone; i++) {
+				if (strcmp(DatumGetName(d)->data, done[i]) == 0) {
+					TPRINTF(TRACE_NOTIFY,
+							"Async_NotifyFrontEnd: duplicate %s",
+							DatumGetName(d)->data);
+					heap_delete(lRel, &lTuple->t_ctid);
+					continue;
+				}
+			}
+			if (ndone < MAX_DONE) {
+				done[ndone++] = pstrdup(DatumGetName(d)->data);
+			}
+		}
+
 		rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
 		heap_replace(lRel, &lTuple->t_ctid, rTuple);
 
 		/* notifying the front end */
+		TPRINTF(TRACE_NOTIFY, "Async_NotifyFrontEnd: notifying %s",
+				DatumGetName(d)->data);
 
 		if (whereToSendOutput == Remote)
 		{
@@ -593,12 +720,12 @@ Async_NotifyFrontEnd()
 			pq_putstr(DatumGetName(d)->data);
 			pq_flush();
 		}
-		else
-			elog(NOTICE, "Async_NotifyFrontEnd: no asynchronous notification to frontend on interactive sessions");
 	}
 	heap_endscan(sRel);
+	RelationUnsetLockForWrite(lRel);
 	heap_close(lRel);
-	CommitTransactionCommand();
+
+	TPRINTF(TRACE_NOTIFY, "Async_NotifyFrontEnd: done");
 }
 
 static int
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 5ad49c8ac4e84a9c1f539fb42944a5c3a3e4e6ef..6366d18717ec0cc91571f5c931d4f5409c21b167 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.86 1998/08/25 21:34:04 scrappy Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.87 1998/08/30 21:05:27 scrappy Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -443,11 +443,41 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 
 		querytree = querytree_list->qtrees[i];
 
-		if (DebugPrintQuery == true)
+		if (DebugPrintQuery)
 		{
-			printf("\n---- \tquery is:\n%s\n", query_string);
-			printf("\n");
-			fflush(stdout);
+			if (DebugPrintQuery > 3) {
+				/* Print the query string as is if query debug level > 3 */
+				TPRINTF(TRACE_QUERY, "query: %s",query_string);
+			} else {
+				/* Print condensed query string to fit in one log line */
+				char	buff[8192+1];
+				char	c,
+						*s,
+						*d;
+				int 	n,
+						is_space=1;
+
+				for (s=query_string,d=buff,n=0; (c=*s) && (n<8192); s++) {
+					switch (c) {
+						case '\r':
+						case '\n':
+						case '\t':
+							c = ' ';
+							/* fall through */
+						case ' ':
+							if (is_space) continue;
+							is_space = 1;
+							break;
+						default:
+							is_space = 0;
+							break;
+					}
+					*d++ = c;
+					n++;
+				}
+				*d = '\0';
+				TPRINTF(TRACE_QUERY, "query: %s",buff);
+			}
 		}
 
 		/* don't rewrite utilites */
@@ -457,11 +487,10 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 			continue;
 		}
 
-		if (DebugPrintParse == true)
+		if (DebugPrintParse)
 		{
-			printf("\n---- \tparser outputs :\n");
+			TPRINTF(TRACE_PARSE, "parser outputs:");
 			nodeDisplay(querytree);
-			printf("\n");
 		}
 
 		/* rewrite queries (retrieve, append, delete, replace) */
@@ -906,9 +935,11 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 	char			firstchar;
 	char			parser_input[MAX_PARSE_BUFFER];
 	char	   		*userName;
-	char	   		*remote_info;
-	char	   		*remote_host;
-	unsigned short 	remote_port = 0;
+
+	/* Used if verbose is set, must be initialized */
+	char	   		*remote_info = "interactive";
+	char	   		*remote_host = "";
+	unsigned short 	remote_port  = 0;
 
 	char	   		*DBDate = NULL;
 	extern int		optind;
@@ -1490,7 +1521,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface");
-		puts("$Revision: 1.86 $ $Date: 1998/08/25 21:34:04 $");
+		puts("$Revision: 1.87 $ $Date: 1998/08/30 21:05:27 $");
 	}
 
 	/* ----------------
diff --git a/src/man/create_sequence.l b/src/man/create_sequence.l
index 0a695fa6bf4708f2877812dbdf2c537fda5470fc..588e70f3944a5db83b6ff75a7245d4bede6ed1d5 100644
--- a/src/man/create_sequence.l
+++ b/src/man/create_sequence.l
@@ -1,6 +1,6 @@
 .\" This is -*-nroff-*-
 .\" XXX standard disclaimer belongs here....
-.\" $Header: /cvsroot/pgsql/src/man/Attic/create_sequence.l,v 1.5 1998/07/14 01:45:25 momjian Exp $
+.\" $Header: /cvsroot/pgsql/src/man/Attic/create_sequence.l,v 1.6 1998/08/30 21:03:19 scrappy Exp $
 .TH "CREATE SEQUENCE" SQL 07/13/98 PostgreSQL PostgreSQL
 .SH NAME
 create sequence - create a new sequence number generator
@@ -82,6 +82,14 @@ given sequence in the current backend session.  Also beware that it
 does not give the last number ever allocated, only the last one allocated
 by this backend.
 .PP
+The function
+.BR setval
+('sequence_name', value)
+may be used to set the current value of the specified sequence.
+The next call to
+.BR nextval
+will return the given value + the sequence increment.
+.PP
 Use a query like
 .nf
 SELECT * FROM <sequence_name>;
@@ -134,6 +142,15 @@ select nextval ('seq');
 -- Use sequence in insert
 --
 insert into table _table_ values (nextval ('seq'),...);
+.nf
+--
+-- Set the sequence value after a copy in
+--
+create function table_id_max() returns int4
+    as 'select max(id) from _table_' 
+    language 'sql';
+copy _table_ from 'input_file';
+select setval('seq', table_id_max());
 .fi
 .SH "SEE ALSO"
 drop_sequence(l).
diff --git a/src/man/listen.l b/src/man/listen.l
index 49801408f7363d2c94da2d629f380d421c8888ec..165fe7ab026165c3801527efe18c82f36b32a66e 100644
--- a/src/man/listen.l
+++ b/src/man/listen.l
@@ -1,6 +1,6 @@
 .\" This is -*-nroff-*-
 .\" XXX standard disclaimer belongs here....
-.\" $Header: /cvsroot/pgsql/src/man/Attic/listen.l,v 1.7 1998/07/09 03:29:09 scrappy Exp $
+.\" $Header: /cvsroot/pgsql/src/man/Attic/listen.l,v 1.8 1998/08/30 21:03:20 scrappy Exp $
 .TH "LISTEN" SQL 03/12/94 PostgreSQL PostgreSQL
 .SH NAME
 listen - listen for notification on a relation
@@ -27,16 +27,19 @@ in order to find out the name of the class to which a given
 notification corresponds.  If this code is not included in 
 the application, the event notification will be queued and 
 never be processed.
+.PP
+Note that
+.IR class_name
+needs not to be a valid class name but can be any ascii string up to 32
+characters long. It must however be eclosed in double-quotes if it is
+not valid as class name.
 .SH "SEE ALSO"
 create_rule(l),
 notify(l),
 select(l),
+unlisten(l),
 libpq.
 .SH BUGS
-There is no way to un-\c
-.BR listen
-except to drop the connection (i.e., restart the backend server).
-.PP
 The
 .IR psql(1)
 command does not poll for asynchronous events.