From 6378fdd971eccc2ad4acd015b8e1baa27e0910a6 Mon Sep 17 00:00:00 2001 From: Bruce Momjian 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 e94ad782cc..42975740ac 100644 --- a/doc/src/sgml/ref/reset.sgml +++ b/doc/src/sgml/ref/reset.sgml @@ -1,5 +1,5 @@ @@ -11,7 +11,8 @@ PostgreSQL documentation RESET - restore the value of a run-time parameter to the default value + restore the value of a run-time parameter to the default value, + or reset all aspects of a session @@ -22,6 +23,7 @@ PostgreSQL documentation RESET name RESET ALL +RESET CONNECTION @@ -50,8 +52,11 @@ SET parameter TO DEFAULT See the SET reference page for details on the - transaction behavior of RESET. + transaction behavior of RESET. RESET + CONNECTION can be used to reset all aspects of + a session, not just parameter values. + @@ -76,7 +81,20 @@ SET parameter TO DEFAULT + + + CONNECTION + + + Reset the all aspects of a session, including runtime parameters, + transaction status, temporary tables, WITH HOLD + cursors, prepared statements, and LISTEN + registrations. + + + + diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 8749a43055..c1edfce8ea 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 0e2622ad13..508ba9eb5c 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 0892ab9fbb..02f8d14c8c 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 28347649df..75b4247771 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 7ac6073936..7b1321a6e6 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * 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 71ddd7dae3..f91901d09b 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 a9c97ea0fd..e398564279 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 cddf628a17..b6ccda39c1 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 362364e5f4..075d3b1152 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 29ad462014..e3d312ef90 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 c73aa41a19..13eff2ca1f 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"); } ;