summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian2006-04-25 14:09:21 +0000
committerBruce Momjian2006-04-25 14:09:21 +0000
commitea70913beee5ea9e7d06ccc2b90c96e93f0228a5 (patch)
tree191f3524b878a7b08f97dd8613e328e9fdb951e3
parenta837fb5ebb64f061bb8eeb13ec3627efee2869d5 (diff)
Add RESET CONNECTION, to reset all aspects of a session.
Hans-J?rgen Sch?nig
-rw-r--r--doc/src/sgml/ref/reset.sgml22
-rw-r--r--src/backend/catalog/namespace.c3
-rw-r--r--src/backend/commands/async.c3
-rw-r--r--src/backend/commands/prepare.c25
-rw-r--r--src/backend/parser/gram.y6
-rw-r--r--src/backend/utils/misc/guc.c31
-rw-r--r--src/backend/utils/mmgr/portalmem.c27
-rw-r--r--src/include/catalog/namespace.h2
-rw-r--r--src/include/commands/async.h1
-rw-r--r--src/include/commands/prepare.h1
-rw-r--r--src/include/utils/portal.h1
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y2
12 files changed, 116 insertions, 8 deletions
diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml
index 34ba63bc94..63a54a8402 100644
--- a/doc/src/sgml/ref/reset.sgml
+++ b/doc/src/sgml/ref/reset.sgml
@@ -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 20bfd532bf..88d99712b6 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -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 69cfea6118..c44e922e4d 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -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 0fbf3ec5b5..302b1b79e0 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -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.
@@ -548,6 +547,30 @@ DeallocateQuery(DeallocateStmt *stmt)
}
/*
+ * 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
*
* If showError is false, dropping a nonexistent statement is a no-op.
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c292907c21..bee4b744f7 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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 34a204b174..eb85c8a2f6 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -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 493ae53a6d..b35a5162fc 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -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 ad31cb507d..a52479006e 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -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 e9961ec4c1..8d472660a1 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -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 d834f0c249..e5338a995c 100644
--- a/src/include/commands/prepare.h
+++ b/src/include/commands/prepare.h
@@ -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 1212cb7c8b..7644c4d778 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -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 e5ad459c9a..576e0e0da8 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -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"); }
;