Skip to content

Commit c2ff31e

Browse files
okbob@github.comCommitfest Bot
authored andcommitted
DISCARD VARIABLES
Implementation of DISCARD VARIABLES commands by removing hash table with session variables and resetting related memory context.
1 parent 560a9ef commit c2ff31e

File tree

11 files changed

+135
-5
lines changed

11 files changed

+135
-5
lines changed

doc/src/sgml/ref/discard.sgml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
24+
DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP | VARIABLES }
2525
</synopsis>
2626
</refsynopsisdiv>
2727

@@ -66,6 +66,16 @@ DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
6666
</listitem>
6767
</varlistentry>
6868

69+
<varlistentry>
70+
<term><literal>VARIABLES</literal></term>
71+
<listitem>
72+
<para>
73+
Resets the value of all session variables. If a variable
74+
is later reused, it is re-initialized to <literal>NULL</literal>.
75+
</para>
76+
</listitem>
77+
</varlistentry>
78+
6979
<varlistentry>
7080
<term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
7181
<listitem>
@@ -93,6 +103,7 @@ SELECT pg_advisory_unlock_all();
93103
DISCARD PLANS;
94104
DISCARD TEMP;
95105
DISCARD SEQUENCES;
106+
DISCARD VARIABLES;
96107
</programlisting></para>
97108
</listitem>
98109
</varlistentry>

src/backend/commands/discard.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "commands/async.h"
1919
#include "commands/discard.h"
2020
#include "commands/prepare.h"
21+
#include "commands/session_variable.h"
2122
#include "commands/sequence.h"
2223
#include "utils/guc.h"
2324
#include "utils/portal.h"
@@ -48,6 +49,10 @@ DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
4849
ResetTempTableNamespace();
4950
break;
5051

52+
case DISCARD_VARIABLES:
53+
ResetSessionVariables();
54+
break;
55+
5156
default:
5257
elog(ERROR, "unrecognized DISCARD target: %d", stmt->target);
5358
}
@@ -75,4 +80,5 @@ DiscardAll(bool isTopLevel)
7580
ResetPlanCache();
7681
ResetTempTableNamespace();
7782
ResetSequenceCaches();
83+
ResetSessionVariables();
7884
}

src/backend/commands/session_variable.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

src/backend/parser/gram.y

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,7 +2146,13 @@ DiscardStmt:
21462146
n->target = DISCARD_SEQUENCES;
21472147
$$ = (Node *) n;
21482148
}
2149+
| DISCARD VARIABLES
2150+
{
2151+
DiscardStmt *n = makeNode(DiscardStmt);
21492152

2153+
n->target = DISCARD_VARIABLES;
2154+
$$ = (Node *) n;
2155+
}
21502156
;
21512157

21522158

src/backend/tcop/utility.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,6 +2953,9 @@ CreateCommandTag(Node *parsetree)
29532953
case DISCARD_SEQUENCES:
29542954
tag = CMDTAG_DISCARD_SEQUENCES;
29552955
break;
2956+
case DISCARD_VARIABLES:
2957+
tag = CMDTAG_DISCARD_VARIABLES;
2958+
break;
29562959
default:
29572960
tag = CMDTAG_UNKNOWN;
29582961
}

src/bin/psql/tab-complete.in.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4241,7 +4241,7 @@ match_previous_words(int pattern_id,
42414241

42424242
/* DISCARD */
42434243
else if (Matches("DISCARD"))
4244-
COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
4244+
COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP", "VARIABLES");
42454245

42464246
/* DO */
42474247
else if (Matches("DO"))

src/include/commands/session_variable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ extern ObjectAddress CreateVariable(ParseState *pstate, CreateSessionVarStmt *st
2929
extern void ExecuteLetStmt(ParseState *pstate, LetStmt *stmt, ParamListInfo params,
3030
QueryEnvironment *queryEnv, QueryCompletion *qc);
3131

32+
extern void ResetSessionVariables(void);
33+
3234
#endif

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4107,6 +4107,7 @@ typedef enum DiscardMode
41074107
DISCARD_PLANS,
41084108
DISCARD_SEQUENCES,
41094109
DISCARD_TEMP,
4110+
DISCARD_VARIABLES,
41104111
} DiscardMode;
41114112

41124113
typedef struct DiscardStmt

src/include/tcop/cmdtaglist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ PG_CMDTAG(CMDTAG_DISCARD_ALL, "DISCARD ALL", false, false, false)
135135
PG_CMDTAG(CMDTAG_DISCARD_PLANS, "DISCARD PLANS", false, false, false)
136136
PG_CMDTAG(CMDTAG_DISCARD_SEQUENCES, "DISCARD SEQUENCES", false, false, false)
137137
PG_CMDTAG(CMDTAG_DISCARD_TEMP, "DISCARD TEMP", false, false, false)
138+
PG_CMDTAG(CMDTAG_DISCARD_VARIABLES, "DISCARD VARIABLES", false, false, false)
138139
PG_CMDTAG(CMDTAG_DO, "DO", false, false, false)
139140
PG_CMDTAG(CMDTAG_DROP_ACCESS_METHOD, "DROP ACCESS METHOD", true, false, false)
140141
PG_CMDTAG(CMDTAG_DROP_AGGREGATE, "DROP AGGREGATE", true, false, false)

src/test/regress/expected/session_variables_dml.out

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,53 @@ drop cascades to session variable svartest_dml.sesvar47
466466
drop cascades to session variable svartest_dml.sesvar48
467467
drop cascades to session variable svartest_dml.sesvar49
468468
DROP ROLE regress_svartest_dml_write_only_role;
469+
CREATE SCHEMA svartest_dml_discard;
470+
CREATE VARIABLE svartest_dml_discard.sesvar50 AS varchar;
471+
LET svartest_dml_discard.sesvar50 = 'Hello';
472+
SELECT VARIABLE(svartest_dml_discard.sesvar50);
473+
sesvar50
474+
----------
475+
Hello
476+
(1 row)
477+
478+
SELECT count(*) FROM pg_get_session_variables_memory() WHERE schema = 'svartest_dml_discard';
479+
count
480+
-------
481+
1
482+
(1 row)
483+
484+
DISCARD ALL;
485+
SELECT count(*) FROM pg_get_session_variables_memory();
486+
count
487+
-------
488+
0
489+
(1 row)
490+
491+
SELECT VARIABLE(svartest_dml_discard.sesvar50);
492+
sesvar50
493+
----------
494+
495+
(1 row)
496+
497+
LET svartest_dml_discard.sesvar50 = 'Hello';
498+
SELECT count(*) FROM pg_get_session_variables_memory();
499+
count
500+
-------
501+
1
502+
(1 row)
503+
504+
DISCARD VARIABLES;
505+
SELECT count(*) FROM pg_get_session_variables_memory();
506+
count
507+
-------
508+
0
509+
(1 row)
510+
511+
SELECT VARIABLE(svartest_dml_discard.sesvar50);
512+
sesvar50
513+
----------
514+
515+
(1 row)
516+
517+
DROP SCHEMA svartest_dml_discard CASCADE;
518+
NOTICE: drop cascades to session variable svartest_dml_discard.sesvar50

0 commit comments

Comments
 (0)