From 16efdb5ec7f28bed9541fc773330e3e2ebe2ed9a Mon Sep 17 00:00:00 2001
From: Neil Conway <neilc@samurai.com>
Date: Thu, 26 Apr 2007 16:13:15 +0000
Subject: [PATCH] Rename the newly-added commands for discarding session state.
 RESET SESSION, RESET PLANS, and RESET TEMP are now DISCARD ALL, DISCARD
 PLANS, and DISCARD TEMP, respectively. This is to avoid confusion with the
 pre-existing RESET variants: the DISCARD commands are not actually similar to
 RESET. Patch from Marko Kreen, with some minor editorialization.

---
 doc/src/sgml/ref/allfiles.sgml     |   3 +-
 doc/src/sgml/ref/discard.sgml      | 107 +++++++++++++++++++++++++++++
 doc/src/sgml/ref/reset.sgml        |  59 +---------------
 doc/src/sgml/reference.sgml        |   3 +-
 src/backend/commands/Makefile      |   4 +-
 src/backend/commands/discard.c     |  71 +++++++++++++++++++
 src/backend/nodes/copyfuncs.c      |  15 +++-
 src/backend/nodes/equalfuncs.c     |  13 +++-
 src/backend/parser/gram.y          |  45 ++++++++++--
 src/backend/parser/keywords.c      |   4 +-
 src/backend/tcop/utility.c         |  39 +++++++----
 src/backend/utils/misc/guc.c       |  33 +--------
 src/backend/utils/mmgr/portalmem.c |   4 +-
 src/bin/psql/tab-complete.c        |  15 +++-
 src/include/commands/discard.h     |  20 ++++++
 src/include/nodes/nodes.h          |   3 +-
 src/include/nodes/parsenodes.h     |  20 +++++-
 src/test/regress/expected/guc.out  |  10 +--
 src/test/regress/sql/guc.sql       |  10 +--
 19 files changed, 345 insertions(+), 133 deletions(-)
 create mode 100644 doc/src/sgml/ref/discard.sgml
 create mode 100644 src/backend/commands/discard.c
 create mode 100644 src/include/commands/discard.h

diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
index 3b9b8b952ee..90ad9adc53c 100644
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.69 2007/01/23 05:07:16 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.70 2007/04/26 16:13:08 neilc Exp $
 PostgreSQL documentation
 Complete list of usable sgml source files in this directory.
 -->
@@ -61,6 +61,7 @@ Complete list of usable sgml source files in this directory.
 <!entity deallocate         system "deallocate.sgml">
 <!entity declare            system "declare.sgml">
 <!entity delete             system "delete.sgml">
+<!entity discard            system "discard.sgml">
 <!entity dropAggregate      system "drop_aggregate.sgml">
 <!entity dropCast           system "drop_cast.sgml">
 <!entity dropConversion     system "drop_conversion.sgml">
diff --git a/doc/src/sgml/ref/discard.sgml b/doc/src/sgml/ref/discard.sgml
new file mode 100644
index 00000000000..731f34136e1
--- /dev/null
+++ b/doc/src/sgml/ref/discard.sgml
@@ -0,0 +1,107 @@
+<!--
+$PostgreSQL: pgsql/doc/src/sgml/ref/discard.sgml,v 1.1 2007/04/26 16:13:09 neilc Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-DISCARD">
+ <refmeta>
+  <refentrytitle id="SQL-DISCARD-TITLE">DISCARD</refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>DISCARD</refname>
+  <refpurpose>Discard internal server state</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="sql-discard">
+  <primary>DISCARD</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+<synopsis>
+DISCARD { ALL | PLANS | TEMPORARY | TEMP }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <command>DISCARD</> releases internal resources associated with a
+   database session. These resources are normally released at the end
+   of the session.
+  </para>
+
+  <para>
+   <command>DISCARD TEMP</> drops all temporary tables created in the
+   current session.  <command>DISCARD PLANS</> releases all internally
+   cached query plans.  <command>DISCARD ALL</> resets a session to
+   its original state, discarding temporary resources and resetting
+   session-local configuration changes.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Parameters</title>
+
+  <variablelist>
+
+   <varlistentry>
+    <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+    <listitem>
+     <para>
+      Drops all temporary tables created in the current session.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><literal>PLANS</literal></term>
+    <listitem>
+     <para>
+      Releases all cached query plans.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><literal>ALL</literal></term>
+    <listitem>
+     <para>
+      Releases all temporary resources associated with the current
+      session and resets the session to its initial state. This has
+      the same effect as executing the following sequence of
+      statements:
+<programlisting>
+SET SESSION AUTHORIZATION DEFAULT;
+RESET ALL;
+DEALLOCATE ALL;
+CLOSE ALL;
+UNLISTEN *;
+DISCARD PLANS;
+DISCARD TEMP;
+</programlisting>
+     </para>
+    </listitem>
+   </varlistentry>
+
+  </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Notes</title>
+
+   <para>
+    <command>DISCARD ALL</> cannot be executed inside a transaction block.
+   </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Compatibility</title>
+
+  <para>
+   <command>DISCARD</command> is a <productname>PostgreSQL</productname> extension.
+  </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml
index e98f7ff56c6..355de891287 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.34 2007/04/12 22:34:45 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/reset.sgml,v 1.35 2007/04/26 16:13:09 neilc Exp $
 PostgreSQL documentation
 -->
 
@@ -22,7 +22,6 @@ PostgreSQL documentation
 <synopsis>
 RESET <replaceable class="PARAMETER">configuration_parameter</replaceable>
 RESET ALL
-RESET { PLANS | SESSION | TEMP | TEMPORARY }
 </synopsis>
  </refsynopsisdiv>
 
@@ -53,15 +52,6 @@ SET <replaceable class="parameter">configuration_parameter</replaceable> TO DEFA
    See the <command>SET</> reference page for details on the
    transaction behavior of <command>RESET</>.
   </para>
-
-  <para>
-   <command>RESET</> can also be used to release internal resources
-   that are usually released at the end of session.  <command>RESET
-   TEMP</> drops all temporary tables created in the current session.
-   <command>RESET PLANS</> releases all internally cached plans.
-   <command>RESET SESSION</> releases all externally visible temporary
-   resources associated with the current session.
-  </para>
  </refsect1>
 
  <refsect1>
@@ -86,56 +76,9 @@ SET <replaceable class="parameter">configuration_parameter</replaceable> TO DEFA
      </para>
     </listitem>
    </varlistentry>
-
-   <varlistentry>
-    <term><literal>TEMP, TEMPORARY</literal></term>
-    <listitem>
-     <para>
-      Drops all temporary tables created in the current session.
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term><literal>PLANS</literal></term>
-    <listitem>
-     <para>
-      Releases all cached query plans.
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term><literal>SESSION</literal></term>
-    <listitem>
-     <para>
-      Releases all temporary resources associated with the current
-      session. This has the same effect as executing the following
-      command sequence:
-<programlisting>
-SET SESSION AUTHORIZATION DEFAULT;
-RESET ALL;
-DEALLOCATE ALL;
-CLOSE ALL;
-UNLISTEN *;
-RESET PLANS;
-RESET TEMP;
-</programlisting>
-     </para>
-    </listitem>
-   </varlistentry>
-
   </variablelist>
  </refsect1>
 
- <refsect1>
-  <title>Notes</title>
-
-   <para>
-    <command>RESET SESSION</> cannot be executed inside a transaction block.
-   </para>
- </refsect1>
-
  <refsect1>
   <title>Examples</title>
 
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
index 06c6c4a21db..06699a5b34b 100644
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.62 2007/01/31 20:56:18 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.63 2007/04/26 16:13:08 neilc Exp $ -->
 
 <part id="reference">
  <title>Reference</title>
@@ -89,6 +89,7 @@
    &deallocate;
    &declare;
    &delete;
+   &discard;
    &dropAggregate;
    &dropCast;
    &dropConversion;
diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile
index f2e5bf52f20..4b25ae6489e 100644
--- a/src/backend/commands/Makefile
+++ b/src/backend/commands/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for backend/commands
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/commands/Makefile,v 1.35 2007/01/20 17:16:11 petere Exp $
+#    $PostgreSQL: pgsql/src/backend/commands/Makefile,v 1.36 2007/04/26 16:13:09 neilc Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global
 
 OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o  \
 	conversioncmds.o copy.o \
-	dbcommands.o define.o explain.o functioncmds.o \
+	dbcommands.o define.o discard.o explain.o functioncmds.o \
 	indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
 	portalcmds.o prepare.o proclang.o \
 	schemacmds.o sequence.o tablecmds.o tablespace.o trigger.o \
diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c
new file mode 100644
index 00000000000..d2ae6defd04
--- /dev/null
+++ b/src/backend/commands/discard.c
@@ -0,0 +1,71 @@
+/*-------------------------------------------------------------------------
+ *
+ * discard.c
+ *	  The implementation of the DISCARD command
+ *
+ * Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL: pgsql/src/backend/commands/discard.c,v 1.1 2007/04/26 16:13:10 neilc Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/xact.h"
+#include "catalog/namespace.h"
+#include "commands/async.h"
+#include "commands/discard.h"
+#include "commands/prepare.h"
+#include "commands/variable.h"
+#include "utils/plancache.h"
+#include "utils/portal.h"
+
+static void DiscardAll(bool isTopLevel);
+
+/*
+ * DISCARD { ALL | TEMP | PLANS }
+ */
+void
+DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
+{
+	switch (stmt->target)
+	{
+		case DISCARD_ALL:
+			DiscardAll(isTopLevel);
+			break;
+
+		case DISCARD_PLANS:
+			ResetPlanCache();
+			break;
+
+		case DISCARD_TEMP:
+			ResetTempTableNamespace();
+			break;
+
+		default:
+			elog(ERROR, "unrecognized DISCARD target: %d", stmt->target);
+	}
+}
+
+static void
+DiscardAll(bool isTopLevel)
+{
+	/*
+	 * Disallow DISCARD ALL in a transaction block. This is arguably
+	 * inconsistent (we don't make a similar check in the command
+	 * sequence that DISCARD ALL is equivalent to), but the idea is
+	 * to catch mistakes: DISCARD ALL inside a transaction block
+	 * would leave the transaction still uncommitted.
+	 */
+	PreventTransactionChain(isTopLevel, "DISCARD ALL");
+
+	SetPGVariable("session_authorization", NIL, false);
+	ResetAllOptions();
+	DropAllPreparedStatements();
+	PortalHashTableDeleteAll();
+	Async_UnlistenAll();
+	ResetPlanCache();
+	ResetTempTableNamespace();
+}
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 9bf57fb87f2..988120a9634 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.373 2007/04/02 03:49:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.374 2007/04/26 16:13:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2589,6 +2589,16 @@ _copyVariableResetStmt(VariableResetStmt *from)
 	return newnode;
 }
 
+static DiscardStmt *
+_copyDiscardStmt(DiscardStmt *from)
+{
+	DiscardStmt *newnode = makeNode(DiscardStmt);
+
+	COPY_SCALAR_FIELD(target);
+
+	return newnode;
+}
+
 static CreateTableSpaceStmt *
 _copyCreateTableSpaceStmt(CreateTableSpaceStmt *from)
 {
@@ -3380,6 +3390,9 @@ copyObject(void *from)
 		case T_VariableResetStmt:
 			retval = _copyVariableResetStmt(from);
 			break;
+		case T_DiscardStmt:
+			retval = _copyDiscardStmt(from);
+			break;
 		case T_CreateTableSpaceStmt:
 			retval = _copyCreateTableSpaceStmt(from);
 			break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 1cc0c343dca..c1500948dca 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.304 2007/04/02 03:49:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.305 2007/04/26 16:13:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1376,6 +1376,14 @@ _equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
 	return true;
 }
 
+static bool
+_equalDiscardStmt(DiscardStmt *a, DiscardStmt *b)
+{
+	COMPARE_SCALAR_FIELD(target);
+
+	return true;
+}
+
 static bool
 _equalCreateTableSpaceStmt(CreateTableSpaceStmt *a, CreateTableSpaceStmt *b)
 {
@@ -2313,6 +2321,9 @@ equal(void *a, void *b)
 		case T_VariableResetStmt:
 			retval = _equalVariableResetStmt(a, b);
 			break;
+		case T_DiscardStmt:
+			retval = _equalDiscardStmt(a, b);
+			break;
 		case T_CreateTableSpaceStmt:
 			retval = _equalCreateTableSpaceStmt(a, b);
 			break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b9728deaada..a69e6989a94 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.589 2007/04/16 01:14:56 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.590 2007/04/26 16:13:11 neilc Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -158,7 +158,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 		CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
 		CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
 		CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
-		CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
+		CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt
 		DropGroupStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
 		DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
 		DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
@@ -382,7 +382,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 
 	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
 	DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
-	DESC DISABLE_P DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
+	DESC DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
 
 	EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT EXCLUDING
 	EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
@@ -416,7 +416,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
 	ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
 
-	PARTIAL PASSWORD PLACING POSITION
+	PARTIAL PASSWORD PLACING PLANS POSITION
 	PRECISION PRESERVE PREPARE PREPARED PRIMARY
 	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
 
@@ -569,6 +569,7 @@ stmt :
 			| DeclareCursorStmt
 			| DefineStmt
 			| DeleteStmt
+			| DiscardStmt
 			| DropAssertStmt
 			| DropCastStmt
 			| DropGroupStmt
@@ -1328,6 +1329,40 @@ CheckPointStmt:
 		;
 
 
+/*****************************************************************************
+ *
+ * DISCARD { ALL | TEMP | PLANS }
+ *
+ *****************************************************************************/
+
+DiscardStmt:
+			DISCARD ALL
+				{
+					DiscardStmt *n = makeNode(DiscardStmt);
+					n->target = DISCARD_ALL;
+					$$ = (Node *) n;
+				}
+			| DISCARD TEMP
+				{
+					DiscardStmt *n = makeNode(DiscardStmt);
+					n->target = DISCARD_TEMP;
+					$$ = (Node *) n;
+				}
+			| DISCARD TEMPORARY
+				{
+					DiscardStmt *n = makeNode(DiscardStmt);
+					n->target = DISCARD_TEMP;
+					$$ = (Node *) n;
+				}
+			| DISCARD PLANS
+				{
+					DiscardStmt *n = makeNode(DiscardStmt);
+					n->target = DISCARD_PLANS;
+					$$ = (Node *) n;
+				}
+		;
+
+
 /*****************************************************************************
  *
  *	ALTER [ TABLE | INDEX ] variations
@@ -8796,6 +8831,7 @@ unreserved_keyword:
 			| DELIMITER
 			| DELIMITERS
 			| DISABLE_P
+			| DISCARD
 			| DOCUMENT_P
 			| DOMAIN_P
 			| DOUBLE_P
@@ -8881,6 +8917,7 @@ unreserved_keyword:
 			| OWNER
 			| PARTIAL
 			| PASSWORD
+			| PLANS
 			| PREPARE
 			| PREPARED
 			| PRESERVE
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 9f6cf1e20e4..5c8ef10a214 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.186 2007/04/02 03:49:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.187 2007/04/26 16:13:12 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -124,6 +124,7 @@ static const ScanKeyword ScanKeywords[] = {
 	{"delimiters", DELIMITERS},
 	{"desc", DESC},
 	{"disable", DISABLE_P},
+	{"discard", DISCARD},
 	{"distinct", DISTINCT},
 	{"do", DO},
 	{"document", DOCUMENT_P},
@@ -269,6 +270,7 @@ static const ScanKeyword ScanKeywords[] = {
 	{"partial", PARTIAL},
 	{"password", PASSWORD},
 	{"placing", PLACING},
+	{"plans", PLANS},
 	{"position", POSITION},
 	{"precision", PRECISION},
 	{"prepare", PREPARE},
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 88adb625d55..9dd700ffe70 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.277 2007/04/12 06:53:47 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.278 2007/04/26 16:13:12 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,6 +29,7 @@
 #include "commands/copy.h"
 #include "commands/dbcommands.h"
 #include "commands/defrem.h"
+#include "commands/discard.h"
 #include "commands/explain.h"
 #include "commands/lockcmds.h"
 #include "commands/portalcmds.h"
@@ -604,10 +605,7 @@ ProcessUtility(Node *parsetree,
 							break;
 
 						case OBJECT_DOMAIN:
-
-							/*
-							 * RemoveDomain does its own permissions checks
-							 */
+							/* RemoveDomain does its own permissions checks */
 							RemoveDomain(names, stmt->behavior,
 										 stmt->missing_ok);
 							break;
@@ -618,10 +616,7 @@ ProcessUtility(Node *parsetree,
 							break;
 
 						case OBJECT_SCHEMA:
-
-							/*
-							 * RemoveSchema does its own permissions checks
-							 */
+							/* RemoveSchema does its own permissions checks */
 							RemoveSchema(names, stmt->behavior,
 										 stmt->missing_ok);
 							break;
@@ -994,6 +989,10 @@ ProcessUtility(Node *parsetree,
 			}
 			break;
 
+		case T_DiscardStmt:
+			DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
+			break;
+
 		case T_CreateTrigStmt:
 			CreateTrigger((CreateTrigStmt *) parsetree, InvalidOid);
 			break;
@@ -1752,12 +1751,22 @@ CreateCommandTag(Node *parsetree)
 			break;
 
 		case T_VariableResetStmt:
-			{
-				VariableResetStmt *stmt = (VariableResetStmt *) parsetree;
-				if (pg_strcasecmp(stmt->name, "session") == 0)
-					tag = "RESET SESSION";
-				else
-					tag = "RESET";
+			tag = "RESET";
+			break;
+
+		case T_DiscardStmt:
+			switch (((DiscardStmt *) parsetree)->target) {
+				case DISCARD_ALL:
+					tag = "DISCARD ALL";
+					break;
+				case DISCARD_PLANS:
+					tag = "DISCARD PLANS";
+					break;
+				case DISCARD_TEMP:
+					tag = "DISCARD TEMP";
+					break;
+				default:
+					tag = "???";
 			}
 			break;
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9b1e813dc6c..a3a8f79a5d1 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.388 2007/04/22 03:52:40 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.389 2007/04/26 16:13:12 neilc Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -5047,30 +5047,6 @@ GetPGVariableResultDesc(const char *name)
 	return tupdesc;
 }
 
-/*
- * RESET SESSION command.
- */
-static void
-ResetSession(bool isTopLevel)
-{
-	/*
-	 * Disallow RESET SESSION in a transaction block. This is arguably
-	 * inconsistent (we don't make a similar check in the command
-	 * sequence that RESET SESSION is equivalent to), but the idea is
-	 * to catch mistakes: RESET SESSION inside a transaction block
-	 * would leave the transaction still uncommitted.
-	 */
-	PreventTransactionChain(isTopLevel, "RESET SESSION");
-
-	SetPGVariable("session_authorization", NIL, false);
-	ResetAllOptions();
-	DropAllPreparedStatements();
-	PortalHashTableDeleteAll();
-	Async_UnlistenAll();
-	ResetPlanCache();
-	ResetTempTableNamespace();
-}
-
 /*
  * RESET command
  */
@@ -5079,13 +5055,6 @@ ResetPGVariable(const char *name, bool isTopLevel)
 {
 	if (pg_strcasecmp(name, "all") == 0)
 		ResetAllOptions();
-	else if (pg_strcasecmp(name, "session") == 0)
-		ResetSession(isTopLevel);
-	else if (pg_strcasecmp(name, "temp") == 0 ||
-			 pg_strcasecmp(name, "temporary") == 0)
-		ResetTempTableNamespace();
-	else if (pg_strcasecmp(name, "plans") == 0)
-		ResetPlanCache();
 	else
 		set_config_option(name,
 						  NULL,
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index eeba207dc94..69bb3e3ebdb 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.101 2007/04/12 06:53:48 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.102 2007/04/26 16:13:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -455,7 +455,7 @@ PortalDrop(Portal portal, bool isTopCommit)
 /*
  * Delete all declared cursors.
  *
- * Used by commands: CLOSE ALL, RESET SESSION
+ * Used by commands: CLOSE ALL, DISCARD ALL
  */
 void
 PortalHashTableDeleteAll(void)
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 090030fd0c3..2ec534cba49 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2007, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.161 2007/04/08 00:26:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.162 2007/04/26 16:13:13 neilc Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -527,8 +527,8 @@ psql_completion(char *text, int start, int end)
 	static const char *const sql_commands[] = {
 		"ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER",
 		"COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
-		"DELETE FROM", "DROP", "END", "EXECUTE", "EXPLAIN", "FETCH", "GRANT",
-		"INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "PREPARE",
+		"DELETE FROM", "DISCARD", "DROP", "END", "EXECUTE", "EXPLAIN", "FETCH",
+		"GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "PREPARE",
 		"REASSIGN", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK",
 		"SAVEPOINT", "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN",
 		"UPDATE", "VACUUM", NULL
@@ -1244,6 +1244,15 @@ psql_completion(char *text, int start, int end)
 	}
 	/* XXX: implement tab completion for DELETE ... USING */
 
+/* DISCARD */
+	else if (pg_strcasecmp(prev_wd, "DISCARD") == 0)
+	{
+		static const char *const list_DISCARD[] =
+		{"ALL", "PLANS", "TEMP", NULL};
+
+		COMPLETE_WITH_LIST(list_DISCARD);
+	}
+
 /* DROP (when not the previous word) */
 	/* DROP AGGREGATE */
 	else if (pg_strcasecmp(prev3_wd, "DROP") == 0 &&
diff --git a/src/include/commands/discard.h b/src/include/commands/discard.h
new file mode 100644
index 00000000000..f2192392ae4
--- /dev/null
+++ b/src/include/commands/discard.h
@@ -0,0 +1,20 @@
+/*-------------------------------------------------------------------------
+ *
+ * discard.h
+ *	  prototypes for discard.c.
+ *
+ *
+ * Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/commands/discard.h,v 1.1 2007/04/26 16:13:13 neilc Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef DISCARD_H
+#define DISCARD_H
+
+#include "nodes/parsenodes.h"
+
+extern void DiscardCommand(DiscardStmt *stmt, bool isTopLevel);
+
+#endif   /* DISCARD_H */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 305be462e10..fc48961c5ca 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.198 2007/04/02 03:49:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.199 2007/04/26 16:13:14 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -273,6 +273,7 @@ typedef enum NodeTag
 	T_VariableSetStmt,
 	T_VariableShowStmt,
 	T_VariableResetStmt,
+	T_DiscardStmt,
 	T_CreateTrigStmt,
 	T_DropPropertyStmt,
 	T_CreatePLangStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index dbc29642f06..09cb4ff5031 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.346 2007/04/16 01:14:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.347 2007/04/26 16:13:14 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1870,6 +1870,24 @@ typedef struct VariableResetStmt
 	char	   *name;
 } VariableResetStmt;
 
+/* ----------------------
+ * Discard Statement
+ * ----------------------
+ */
+
+typedef enum DiscardMode
+{
+	DISCARD_ALL,
+	DISCARD_PLANS,
+	DISCARD_TEMP
+} DiscardMode;
+
+typedef struct DiscardStmt
+{
+	NodeTag		type;
+	DiscardMode	target;
+} DiscardStmt;
+
 /* ----------------------
  *		LOCK Statement
  * ----------------------
diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out
index 484cc356e7f..d8ad5667ab7 100644
--- a/src/test/regress/expected/guc.out
+++ b/src/test/regress/expected/guc.out
@@ -426,7 +426,7 @@ SELECT '2006-08-13 12:34:56'::timestamptz;
 (1 row)
 
 --
--- Test RESET TEMP
+-- Test DISCARD TEMP
 --
 CREATE TEMP TABLE reset_test ( data text ) ON COMMIT DELETE ROWS;
 SELECT relname FROM pg_class WHERE relname = 'reset_test';
@@ -435,14 +435,14 @@ SELECT relname FROM pg_class WHERE relname = 'reset_test';
  reset_test
 (1 row)
 
-RESET TEMP;
+DISCARD TEMP;
 SELECT relname FROM pg_class WHERE relname = 'reset_test';
  relname 
 ---------
 (0 rows)
 
 --
--- Test RESET SESSION
+-- Test DISCARD ALL
 --
 -- do changes
 DECLARE foo CURSOR WITH HOLD FOR SELECT 1;
@@ -489,8 +489,8 @@ SELECT current_user = 'temp_reset_user';
  t
 (1 row)
 
--- big RESET
-RESET SESSION;
+-- discard everything
+DISCARD ALL;
 -- look again
 SELECT relname FROM pg_listener;
  relname 
diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql
index 274007a2c33..a25a13820d7 100644
--- a/src/test/regress/sql/guc.sql
+++ b/src/test/regress/sql/guc.sql
@@ -125,15 +125,15 @@ SHOW datestyle;
 SELECT '2006-08-13 12:34:56'::timestamptz;
 
 --
--- Test RESET TEMP
+-- Test DISCARD TEMP
 --
 CREATE TEMP TABLE reset_test ( data text ) ON COMMIT DELETE ROWS;
 SELECT relname FROM pg_class WHERE relname = 'reset_test';
-RESET TEMP;
+DISCARD TEMP;
 SELECT relname FROM pg_class WHERE relname = 'reset_test';
 
 --
--- Test RESET SESSION
+-- Test DISCARD ALL
 --
 
 -- do changes
@@ -151,8 +151,8 @@ SELECT name FROM pg_cursors;
 SHOW vacuum_cost_delay;
 SELECT relname from pg_class where relname = 'tmp_foo';
 SELECT current_user = 'temp_reset_user';
--- big RESET
-RESET SESSION;
+-- discard everything
+DISCARD ALL;
 -- look again
 SELECT relname FROM pg_listener;
 SELECT name FROM pg_prepared_statements;
-- 
GitLab