From 6378fdd971eccc2ad4acd015b8e1baa27e0910a6 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Tue, 25 Apr 2006 14:09:21 +0000
Subject: [PATCH] Add RESET CONNECTION, to reset all aspects of a session.

Hans-J?rgen Sch?nig
---
 doc/src/sgml/ref/reset.sgml           | 24 ++++++++++++++++---
 src/backend/catalog/namespace.c       |  5 ++--
 src/backend/commands/async.c          |  5 ++--
 src/backend/commands/prepare.c        | 27 ++++++++++++++++++++--
 src/backend/parser/gram.y             |  8 ++++++-
 src/backend/utils/misc/guc.c          | 33 +++++++++++++++++++++++++--
 src/backend/utils/mmgr/portalmem.c    | 29 ++++++++++++++++++++++-
 src/include/catalog/namespace.h       |  4 +++-
 src/include/commands/async.h          |  3 ++-
 src/include/commands/prepare.h        |  3 ++-
 src/include/utils/portal.h            |  3 ++-
 src/interfaces/ecpg/preproc/preproc.y |  4 +++-
 12 files changed, 128 insertions(+), 20 deletions(-)

diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml
index e94ad782cc9..42975740ac8 100644
--- a/doc/src/sgml/ref/reset.sgml
+++ b/doc/src/sgml/ref/reset.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/reset.sgml,v 1.26 2003/12/14 00:15:03 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/reset.sgml,v 1.27 2006/04/25 14:09:06 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -11,7 +11,8 @@ PostgreSQL documentation
 
  <refnamediv>
   <refname>RESET</refname>
-  <refpurpose>restore the value of a run-time parameter to the default value</refpurpose>
+  <refpurpose>restore the value of a run-time parameter to the default value,
+  or reset all aspects of a session</refpurpose>
  </refnamediv>
 
  <indexterm zone="sql-reset">
@@ -22,6 +23,7 @@ PostgreSQL documentation
 <synopsis>
 RESET <replaceable class="PARAMETER">name</replaceable>
 RESET ALL
+RESET CONNECTION
 </synopsis>
  </refsynopsisdiv>
   
@@ -50,8 +52,11 @@ SET <replaceable class="parameter">parameter</replaceable> TO DEFAULT
 
   <para>
    See the <command>SET</> reference page for details on the
-   transaction behavior of <command>RESET</>.
+   transaction behavior of <command>RESET</>.  <command>RESET
+   CONNECTION</command> can be used to reset all aspects of
+   a session, not just parameter values.
   </para>
+
  </refsect1>
 
  <refsect1>
@@ -76,7 +81,20 @@ SET <replaceable class="parameter">parameter</replaceable> TO DEFAULT
      </para>
     </listitem>
    </varlistentry>
+
+   <varlistentry>
+    <term><literal>CONNECTION</literal></term>
+    <listitem>
+     <para>
+      Reset the all aspects of a session, including runtime parameters,
+      transaction status, temporary tables, <literal>WITH HOLD</literal>
+      cursors, prepared statements, and <command>LISTEN</command>
+      registrations.
+     </para>
+    </listitem>
+   </varlistentry>
   </variablelist>
+
  </refsect1>
 
  <refsect1>
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 8749a430551..c1edfce8ea8 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.82 2006/03/05 15:58:22 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.83 2006/04/25 14:09:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -134,7 +134,6 @@ char	   *namespace_search_path = NULL;
 /* Local functions */
 static void recomputeNamespacePath(void);
 static void InitTempTableNamespace(void);
-static void RemoveTempRelations(Oid tempNamespaceId);
 static void RemoveTempRelationsCallback(int code, Datum arg);
 static void NamespaceCallback(Datum arg, Oid relid);
 
@@ -1729,7 +1728,7 @@ AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
  * in order to clean out any relations that might have been created by
  * a crashed backend.
  */
-static void
+void
 RemoveTempRelations(Oid tempNamespaceId)
 {
 	ObjectAddress object;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 0e2622ad13a..508ba9eb5cb 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.129 2006/03/05 15:58:23 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.130 2006/04/25 14:09:10 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -127,7 +127,6 @@ static bool unlistenExitRegistered = false;
 bool		Trace_notify = false;
 
 
-static void Async_UnlistenAll(void);
 static void Async_UnlistenOnExit(int code, Datum arg);
 static void ProcessIncomingNotify(void);
 static void NotifyMyFrontEnd(char *relname, int32 listenerPID);
@@ -335,7 +334,7 @@ Async_Unlisten(const char *relname)
  *
  *--------------------------------------------------------------
  */
-static void
+void
 Async_UnlistenAll(void)
 {
 	Relation	lRel;
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 0892ab9fbb0..02f8d14c8c8 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -10,7 +10,7 @@
  * Copyright (c) 2002-2006, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.50 2006/04/22 01:25:58 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.51 2006/04/25 14:09:11 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,7 +33,6 @@
 #include "utils/hsearch.h"
 #include "utils/memutils.h"
 
-
 /*
  * The hash table in which prepared queries are stored. This is
  * per-backend: query plans are not shared between backends.
@@ -547,6 +546,30 @@ DeallocateQuery(DeallocateStmt *stmt)
 	DropPreparedStatement(stmt->name, true);
 }
 
+/*
+ * Remove all prepared plans from the backend.
+ */
+void
+DropAllPreparedStatements(void)
+{
+	PreparedStatement	*prep_statement;
+	HASH_SEQ_STATUS         status;
+
+	if	(!prepared_queries)
+		return;
+
+	hash_seq_init(&status, prepared_queries);
+
+	while ((prep_statement = (PreparedStatement *) hash_seq_search(&status)))
+	{
+		DropDependentPortals(prep_statement->context);
+
+		/* Flush the context holding the subsidiary data */
+		MemoryContextDelete(prep_statement->context);
+                hash_search(prepared_queries, prep_statement->stmt_name, HASH_REMOVE, NULL);
+	}
+}
+
 /*
  * Internal version of DEALLOCATE
  *
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 28347649df8..75b42477712 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.540 2006/04/24 22:59:19 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.541 2006/04/25 14:09:12 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -1244,6 +1244,12 @@ VariableResetStmt:
 					n->name = $2;
 					$$ = (Node *) n;
 				}
+			| RESET CONNECTION
+				{
+					VariableResetStmt *n = makeNode(VariableResetStmt);
+					n->name = "connection";
+					$$ = (Node *) n;
+				}
 			| RESET TIME ZONE
 				{
 					VariableResetStmt *n = makeNode(VariableResetStmt);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 7ac60739362..7b1321a6e6d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.315 2006/04/10 21:53:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.316 2006/04/25 14:09:15 momjian Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -32,6 +32,7 @@
 #include "catalog/namespace.h"
 #include "catalog/pg_type.h"
 #include "commands/async.h"
+#include "commands/prepare.h"
 #include "commands/variable.h"
 #include "commands/vacuum.h"
 #include "executor/executor.h"
@@ -53,6 +54,7 @@
 #include "postmaster/bgwriter.h"
 #include "postmaster/syslogger.h"
 #include "postmaster/postmaster.h"
+#include "storage/backendid.h"
 #include "storage/bufmgr.h"
 #include "storage/fd.h"
 #include "storage/freespace.h"
@@ -61,11 +63,13 @@
 #include "tcop/tcopprot.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
+#include "utils/hsearch.h"
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
+#include "utils/portal.h"
+#include "utils/syscache.h"
 #include "pgstat.h"
 
-
 #ifndef PG_KRB_SRVTAB
 #define PG_KRB_SRVTAB ""
 #endif
@@ -4649,8 +4653,33 @@ GetPGVariableResultDesc(const char *name)
 void
 ResetPGVariable(const char *name)
 {
+	char			namespaceName[NAMEDATALEN];
+	Oid			namespaceId;
+
 	if (pg_strcasecmp(name, "all") == 0)
+		/* resetting all GUC variables */
 		ResetAllOptions();
+	else if	(pg_strcasecmp(name, "connection") == 0)
+	{
+		ResetAllOptions();
+
+		/* Clean temp-tables */
+		snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d",
+				 MyBackendId);
+		namespaceId = GetSysCacheOid(NAMESPACENAME,
+									 CStringGetDatum(namespaceName), 0, 0, 0);
+		RemoveTempRelations(namespaceId);
+
+		DropAllPreparedStatements();
+
+		Async_UnlistenAll();
+
+		/* Delete cursors, including WITH HOLD */
+		PortalHashTableDeleteAll();
+
+		if (IsTransactionBlock())
+			UserAbortTransactionBlock();
+	}
 	else
 		set_config_option(name,
 						  NULL,
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 71ddd7dae36..f91901d09b1 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.85 2006/03/05 15:58:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.86 2006/04/25 14:09:16 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -402,6 +402,9 @@ DropDependentPortals(MemoryContext queryContext)
 	HASH_SEQ_STATUS status;
 	PortalHashEnt *hentry;
 
+	if (PortalHashTable == NULL)
+		return;
+
 	hash_seq_init(&status, PortalHashTable);
 
 	while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
@@ -413,6 +416,30 @@ DropDependentPortals(MemoryContext queryContext)
 	}
 }
 
+/*
+ * Delete all WITH HOLD cursors, used by RESET CONNECTION
+ */
+void
+PortalHashTableDeleteAll(void)
+{
+	HASH_SEQ_STATUS status;
+	PortalHashEnt *hentry;
+
+	if (PortalHashTable == NULL)
+		return;
+
+	hash_seq_init(&status, PortalHashTable);
+
+	while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
+	{
+		Portal		portal = hentry->portal;
+
+		if	((portal->cursorOptions & CURSOR_OPT_HOLD) &&
+			 portal->status != PORTAL_ACTIVE)
+			PortalDrop(portal, false);
+	}
+}
+
 
 /*
  * Pre-commit processing for portals.
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index a9c97ea0fd8..e3985642793 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.39 2006/03/05 15:58:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.40 2006/04/25 14:09:16 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -74,6 +74,8 @@ extern void PopSpecialNamespace(Oid namespaceId);
 extern Oid	FindConversionByName(List *conname);
 extern Oid	FindDefaultConversionProc(int4 for_encoding, int4 to_encoding);
 
+extern void RemoveTempRelations(Oid tempNamespaceId);
+
 /* initialization & transaction cleanup code */
 extern void InitializeSearchPath(void);
 extern void AtEOXact_Namespace(bool isCommit);
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index cddf628a170..b6ccda39c1f 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/async.h,v 1.31 2006/03/05 15:58:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/async.h,v 1.32 2006/04/25 14:09:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,7 @@ extern bool Trace_notify;
 extern void Async_Notify(const char *relname);
 extern void Async_Listen(const char *relname);
 extern void Async_Unlisten(const char *relname);
+extern void Async_UnlistenAll(void);
 
 /* perform (or cancel) outbound notify processing at transaction commit */
 extern void AtCommit_Notify(void);
diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h
index 362364e5f46..075d3b11520 100644
--- a/src/include/commands/prepare.h
+++ b/src/include/commands/prepare.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 2002-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.18 2006/03/05 15:58:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.19 2006/04/25 14:09:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -62,6 +62,7 @@ extern void StorePreparedStatement(const char *stmt_name,
 extern PreparedStatement *FetchPreparedStatement(const char *stmt_name,
 					   bool throwError);
 extern void DropPreparedStatement(const char *stmt_name, bool showError);
+extern void DropAllPreparedStatements(void);
 extern List *FetchPreparedStatementParams(const char *stmt_name);
 extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt);
 extern bool PreparedStatementReturnsTuples(PreparedStatement *stmt);
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index 29ad4620140..e3d312ef907 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -39,7 +39,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/portal.h,v 1.59 2006/03/05 15:59:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/portal.h,v 1.60 2006/04/25 14:09:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -200,6 +200,7 @@ extern void AtSubAbort_Portals(SubTransactionId mySubid,
 extern void AtSubCleanup_Portals(SubTransactionId mySubid);
 extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
 extern Portal CreateNewPortal(void);
+extern void PortalHashTableDeleteAll(void);
 extern void PortalDrop(Portal portal, bool isTopCommit);
 extern void DropDependentPortals(MemoryContext queryContext);
 extern Portal GetPortalByName(const char *name);
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index c73aa41a19f..13eff2ca1f1 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.321 2006/03/07 01:00:19 tgl Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.322 2006/04/25 14:09:21 momjian Exp $ */
 
 /* Copyright comment */
 %{
@@ -1196,6 +1196,8 @@ VariableResetStmt:	RESET var_name
 			{ $$ = make_str("reset transaction isolation level"); }
 		| RESET SESSION AUTHORIZATION
 			{ $$ = make_str("reset session authorization"); }
+		| RESET CONNECTION
+			{ $$ = make_str("reset connection"); }
 		| RESET ALL
 			{ $$ = make_str("reset all"); }
 		;
-- 
GitLab