@@ -103,7 +103,13 @@ pg_variable_cache_callback(Datum arg, int cacheid, uint32 hashvalue)
103103
104104 elog (DEBUG1 , "pg_variable_cache_callback %u %u" , cacheid , hashvalue );
105105
106- Assert (sessionvars );
106+ /*
107+ * There is no guarantee of session variables being initialized, even when
108+ * receiving an invalidation callback, as DISCARD [ ALL | VARIABLES ]
109+ * destroys the hash table entirely.
110+ */
111+ if (!sessionvars )
112+ return ;
107113
108114 /*
109115 * If the hashvalue is not specified, we have to recheck all currently
@@ -657,8 +663,8 @@ pg_get_session_variables_memory(PG_FUNCTION_ARGS)
657663
658664 /*
659665 * It is also possible that a variable has been dropped and
660- * someone created a new variable with the same object ID.
661- * Use the catalog information only if that is not the case.
666+ * someone created a new variable with the same object ID. Use
667+ * the catalog information only if that is not the case.
662668 */
663669 if (svar -> create_lsn == varform -> varcreate_lsn )
664670 {
@@ -700,3 +706,23 @@ pg_get_session_variables_memory(PG_FUNCTION_ARGS)
700706
701707 return (Datum ) 0 ;
702708}
709+
710+ /*
711+ * Fast drop of the complete content of the session variables hash table, and
712+ * cleanup of any list that wouldn't be relevant anymore.
713+ * This is used by the DISCARD VARIABLES (and DISCARD ALL) command.
714+ */
715+ void
716+ ResetSessionVariables (void )
717+ {
718+ /* destroy hash table and reset related memory context */
719+ if (sessionvars )
720+ {
721+ hash_destroy (sessionvars );
722+ sessionvars = NULL ;
723+ }
724+
725+ /* release memory allocated by session variables */
726+ if (SVariableMemoryContext != NULL )
727+ MemoryContextReset (SVariableMemoryContext );
728+ }
0 commit comments