From efc1b0b978781eebcdf92d1d1a88119c8aa49c0b Mon Sep 17 00:00:00 2001
From: "okbob@github.com" <pavel.stehule@gmail.com>
Date: Mon, 24 Nov 2025 20:04:16 +0100
Subject: [PATCH 07/11] DISCARD TEMP

---
 doc/src/sgml/ref/discard.sgml                 |  3 ++-
 src/backend/commands/discard.c                |  3 +++
 src/backend/commands/session_variable.c       | 20 +++++++++++++++++++
 src/include/commands/session_variable.h       |  2 ++
 .../expected/session_variables_ddl.out        |  7 +++++++
 .../regress/sql/session_variables_ddl.sql     | 10 ++++++++++
 6 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/discard.sgml b/doc/src/sgml/ref/discard.sgml
index bf44c523cac..2700f7b7cd0 100644
--- a/doc/src/sgml/ref/discard.sgml
+++ b/doc/src/sgml/ref/discard.sgml
@@ -70,7 +70,8 @@ DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
     <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
     <listitem>
      <para>
-      Drops all temporary tables created in the current session.
+      Drops all temporary tables and temporary session variables created in
+      the current session.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c
index 17d172df076..0a33c949fce 100644
--- a/src/backend/commands/discard.c
+++ b/src/backend/commands/discard.c
@@ -19,6 +19,7 @@
 #include "commands/discard.h"
 #include "commands/prepare.h"
 #include "commands/sequence.h"
+#include "commands/session_variable.h"
 #include "storage/lock.h"
 #include "utils/guc.h"
 #include "utils/portal.h"
@@ -47,6 +48,7 @@ DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
 
 		case DISCARD_TEMP:
 			ResetTempTableNamespace();
+			ResetSessionVariables();
 			break;
 
 		default:
@@ -76,4 +78,5 @@ DiscardAll(bool isTopLevel)
 	ResetPlanCache();
 	ResetTempTableNamespace();
 	ResetSequenceCaches();
+	ResetSessionVariables();
 }
diff --git a/src/backend/commands/session_variable.c b/src/backend/commands/session_variable.c
index abcb0bb531a..c75f851bad2 100644
--- a/src/backend/commands/session_variable.c
+++ b/src/backend/commands/session_variable.c
@@ -411,3 +411,23 @@ ExecuteLetStmt(ParseState *pstate,
 
 	PopActiveSnapshot();
 }
+
+/*
+ * Fast drop of the complete content of the session variables hash table, and
+ * cleanup of any list that wouldn't be relevant anymore.
+ * This is used by the DISCARD TEMP.
+ */
+void
+ResetSessionVariables(void)
+{
+	/* destroy hash table and reset related memory context */
+	if (sessionvars)
+	{
+		hash_destroy(sessionvars);
+		sessionvars = NULL;
+	}
+
+	/* release memory allocated by session variables */
+	if (SVariableMemoryContext != NULL)
+		MemoryContextReset(SVariableMemoryContext);
+}
diff --git a/src/include/commands/session_variable.h b/src/include/commands/session_variable.h
index c4b4d9e6832..cc1aa7ce23b 100644
--- a/src/include/commands/session_variable.h
+++ b/src/include/commands/session_variable.h
@@ -37,4 +37,6 @@ extern void get_session_variable_type_typmod_collid(char *varname,
 extern void ExecuteLetStmt(ParseState *pstate, LetStmt *stmt, ParamListInfo params,
 						   QueryEnvironment *queryEnv, QueryCompletion *qc);
 
+extern void ResetSessionVariables(void);
+
 #endif
diff --git a/src/test/regress/expected/session_variables_ddl.out b/src/test/regress/expected/session_variables_ddl.out
index 45c2d27ab44..c36febd894e 100644
--- a/src/test/regress/expected/session_variables_ddl.out
+++ b/src/test/regress/expected/session_variables_ddl.out
@@ -41,3 +41,10 @@ DROP VARIABLE x;
 SET ROLE TO DEFAULT;
 DROP ROLE regress_session_variable_test_role_01;
 DROP ROLE regress_session_variable_test_role_02;
+CREATE TEMP VARIABLE x AS int;
+-- should fail
+CREATE TEMP VARIABLE x AS int;
+ERROR:  session variable "x" already exists
+DISCARD TEMP;
+-- should be ok
+CREATE TEMP VARIABLE x AS int;
diff --git a/src/test/regress/sql/session_variables_ddl.sql b/src/test/regress/sql/session_variables_ddl.sql
index 34f34dd898f..7fd739d6677 100644
--- a/src/test/regress/sql/session_variables_ddl.sql
+++ b/src/test/regress/sql/session_variables_ddl.sql
@@ -54,3 +54,13 @@ DROP VARIABLE x;
 SET ROLE TO DEFAULT;
 DROP ROLE regress_session_variable_test_role_01;
 DROP ROLE regress_session_variable_test_role_02;
+
+CREATE TEMP VARIABLE x AS int;
+
+-- should fail
+CREATE TEMP VARIABLE x AS int;
+
+DISCARD TEMP;
+
+-- should be ok
+CREATE TEMP VARIABLE x AS int;
-- 
2.53.0

