public inbox for [email protected]
help / color / mirror / Atom feedFrom: Laurenz Albe <[email protected]>
To: Pavel Stehule <[email protected]>
Cc: Erik Rijkers <[email protected]>
Cc: Michael Paquier <[email protected]>
Cc: Amit Kapila <[email protected]>
Cc: DUVAL REMI <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: proposal: schema variables
Date: Thu, 24 Oct 2024 11:29:02 +0300
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <CAFj8pRBoGBKopkiTa4ki3dMgy-cSTRZ-BQPKOq7=Tk0SSNsowA@mail.gmail.com>
<CAFj8pRBCiWn12H9FHymYs17fk68nRd9Xpn+SYf18TLdb2YSUrQ@mail.gmail.com>
<CAA4eK1JV-Ox0oRFdXnPqXSzM84wTR5QFkRzCpNVF_+0FNjS5Mg@mail.gmail.com>
<CAFj8pRByCCcgDkeXyafAnH6LgxtAyCVwg6yfJAhyTY6GLscfZg@mail.gmail.com>
<CAFj8pRBvUonC_ug3F=w1Q55Dp=DggojvAeL7Vmh14Q-WhFHxzw@mail.gmail.com>
<CAFj8pRDj72P-f=SUygtOXnTOBQ0RzmL_fN=wLfaCzcbPVpGgzw@mail.gmail.com>
<CAFj8pRDD2GQaJ_iDT4vSVe658+oHRXU2S2af7Y1-it9jaP8VFg@mail.gmail.com>
<[email protected]>
<CAFj8pRAFktynx5wkanv5SRuzXkZgXu77XpVACiSE=v7i1xHFbw@mail.gmail.com>
<CAFj8pRA=bn_g5T2AZduy5gNOQoOnUJ+pMHmnRMHi6mR0n=TAsA@mail.gmail.com>
<[email protected]>
<CAFj8pRC9de05HSb4tEHDUwJ98+4Wh30W-rJrNOPnTz6ARcv0Fw@mail.gmail.com>
<CAFj8pRBC5Wz1xHKKBmKsM0xYN0+PdSZ5oXPsk5SZt+VprdUW3A@mail.gmail.com>
<CAFj8pRAh4pzMoZrKCLt9h+Lr2L=vhgs2PjAF45uLbp_7sijM5w@mail.gmail.com>
<CAFj8pRA-kxQ1oErcuDeUKYsrgwB5XGLhquatwxOe3dCVy1gcyQ@mail.gmail.com>
<[email protected]>
<CAFj8pRBbt2xhY9PyabOY0ZN+Aig6ee3oCon-DM9qi0Uw_3qfbw@mail.gmail.com>
<CAFj8pRDSa52J7kPmCYXgq1BBbu3YBXwpdSOVpjgU=hnE2k04Cw@mail.gmail.com>
<CAFj8pRD+QiWOoPrFk2NnPs3t5Eaf4X=aGRV-9ww11cnPP+fV4g@mail.gmail.com>
<[email protected]>
<CAFj8pRCGTjqHvH9oeiSf4T6Bydhk9pm033DxxibgF+B7SHC6MQ@mail.gmail.com>
<CAFj8pRAzNDhFgbZnT0T0mJ7ygA1Qje1Hc0TiKwXM8++kGooPYg@mail.gmail.com>
<[email protected]>
<CAFj8pRBarjJYfkN-0-i=JRZJ4PTOYC+K7XgAhfdDqWGqRiPkyw@mail.gmail.com>
<CAFj8pRDqdWdCULxd5asbKs5C4e9kT2TuKBkR5L-e1=hP5wF2uw@mail.gmail.com>
<[email protected]>
<CAFj8pRCPW56pFr0F0BcasdXjFeo3SFixNSpWKaBk0ibvznum-A@mail.gmail.com>
<CAFj8pRD1Feit93CgwmYm1Q=X+M+AZqffCEZPFQ7qEMNHZRN4fA@mail.gmail.com>
<CAFj8pRCc=B9-FRQg5eWDSkGwS2vpkq88hR6042cmPPizHuEGSA@mail.gmail.com>
<CAFj8pRBk8x7afUXKLBOU-Ctg6A7QJvTAGGVEi0b6Jc8YTe8nUg@mail.gmail.com>
<CAFj8pRCSwHQ4BJUbjF2YEausK1Z6+ejMyedpqAnWJbG+FEJDLw@mail.gmail.com>
<CAFj8pRAbY+N+UqjqgESL5x-bsGmV+aVyyUkxUSgaGDZToZjDqQ@mail.gmail.com>
<CAFj8pRBzKcqzj=23BHfv1QaXHt=2_SN=uhdR3rb_dAVQoit7ug@mail.gmail.com>
<CAFj8pRCi-n6SzkAB+OHG=TZvL13xxta_qgffBLDOY0HEBqDhvg@mail.gmail.com>
<[email protected]>
<CAFj8pRBaD0_bMrCREWnVLfcTMdc0v7ns7Rt=sEvd1EoFmLfarQ@mail.gmail.com>
<[email protected]>
<CAFj8pRDXo-RRcy2VFDm_vzv3Eaaz6Ex=X19up=x8W4COyBNmaQ@mail.gmail.com>
<[email protected]>
<CAFj8pRDgraz64HHcCoFGCKDM1Cxv1ukELsqfsxux4JP3PM6RyQ@mail.gmail.com>
<[email protected]>
<CAFj8pRAsjr0pzQpQeRrQ-wR-ew1oTc6qkW=4355KveN1jKQ+1Q@mail.gmail.com>
<[email protected]>
<[email protected]>
<[email protected]>
<CAFj8pRDF-F5diNTXr206QfQFauFNK1vu_7NARXd0dtdwGTWLMQ@mail.gmail.com>
<[email protected]>
<CAFj8pRCy8NTG3ewOrH0KLQgrMpVMSzPjhoLKW=c1Jjz8QWNSKw@mail.gmail.com>
<CAFj8pRB-ey7mCnKqMhBBrkv2mXOvTLfAEBy2LZxQsWPCBvguGQ@mail.gmail.com>
<[email protected]>
<CAFj8pRBvUwfs96MX2_=unHQ107diUOK4S_WD=E4XBXkpXG3VjA@mail.gmail.com>
<CAFj8pRCDWjgo=yLEK-jRDe5VwuNSQSmMqPPmysQf9nHA8gifnw@mail.gmail.com>
<CAFj8pRA2jbXRTGgM1co8gLCNttgaH8miRUSSauMJKWgousDsDg@mail.gmail.com>
<CAFj8pRA6nJRg8oq5k_Cdk5oH5_FjtViG8XLmHKrkqOuiMT_CKQ@mail.gmail.com>
<CAFj8pRBWMLP3Vyr8z+19eaiJKQoVtBfmDhNJFKXDX6uFzd4vBQ@mail.gmail.com>
<[email protected]>
... and here is a review for patch 4
I didn't change any code, just added the odd article to a comment.
While running the regression tests with "make installcheck", I noticed two problems:
--- /home/laurenz/postgresql/src/test/regress/expected/session_variables.out 2024-10-24 11:14:06.717663613 +0300
+++ /home/laurenz/postgresql/src/test/regress/results/session_variables.out 2024-10-24 11:15:37.999286228 +0300
@@ -30,6 +30,7 @@
GRANT ALL ON SCHEMA svartest TO regress_variable_owner;
CREATE VARIABLE svartest.var1 AS int;
CREATE ROLE regress_variable_reader;
+ERROR: role "regress_variable_reader" already exists
I suggest that patch 0001 should drop role "regress_variable_reader" again.
@@ -107,7 +108,7 @@
CONTEXT: SQL function "sqlfx" statement 1
SELECT plpgsqlfx(20);
ERROR: permission denied for session variable var1
-CONTEXT: SQL expression "$1 + var1"
+CONTEXT: PL/pgSQL expression "$1 + var1"
That looks like bit rot from your commit 4af123ad45.
Yours,
Laurenz Albe
Attachments:
[text/x-patch] v20241024-0004-DISCARD-VARIABLES.patch (9.6K, 2-v20241024-0004-DISCARD-VARIABLES.patch)
download | inline diff:
From 027fb062ecc0840bc5c2d135ebbc8ddc6b046f96 Mon Sep 17 00:00:00 2001
From: Laurenz Albe <[email protected]>
Date: Thu, 24 Oct 2024 11:17:12 +0300
Subject: [PATCH v20241024] DISCARD VARIABLES
Implementation of DISCARD VARIABLES commands by removing hash table with session variables
and resetting related memory context.
---
doc/src/sgml/ref/discard.sgml | 13 +++-
src/backend/commands/discard.c | 6 ++
src/backend/commands/session_variable.c | 28 ++++++++-
src/backend/parser/gram.y | 6 ++
src/backend/tcop/utility.c | 3 +
src/bin/psql/tab-complete.in.c | 2 +-
src/include/commands/session_variable.h | 2 +
src/include/nodes/parsenodes.h | 1 +
src/include/tcop/cmdtaglist.h | 1 +
.../regress/expected/session_variables.out | 63 +++++++++++++++++++
src/test/regress/sql/session_variables.sql | 36 +++++++++++
11 files changed, 158 insertions(+), 3 deletions(-)
diff --git a/doc/src/sgml/ref/discard.sgml b/doc/src/sgml/ref/discard.sgml
index bf44c523cac..61b967f9c9b 100644
--- a/doc/src/sgml/ref/discard.sgml
+++ b/doc/src/sgml/ref/discard.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
-DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
+DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP | VARIABLES }
</synopsis>
</refsynopsisdiv>
@@ -66,6 +66,16 @@ DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>VARIABLES</literal></term>
+ <listitem>
+ <para>
+ Resets the value of all session variables. If a variable
+ is later reused, it is re-initialized to <literal>NULL</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
<listitem>
@@ -93,6 +103,7 @@ SELECT pg_advisory_unlock_all();
DISCARD PLANS;
DISCARD TEMP;
DISCARD SEQUENCES;
+DISCARD VARIABLES;
</programlisting></para>
</listitem>
</varlistentry>
diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c
index 92d983ac748..d06ebaba6f4 100644
--- a/src/backend/commands/discard.c
+++ b/src/backend/commands/discard.c
@@ -18,6 +18,7 @@
#include "commands/async.h"
#include "commands/discard.h"
#include "commands/prepare.h"
+#include "commands/session_variable.h"
#include "commands/sequence.h"
#include "utils/guc.h"
#include "utils/portal.h"
@@ -48,6 +49,10 @@ DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
ResetTempTableNamespace();
break;
+ case DISCARD_VARIABLES:
+ ResetSessionVariables();
+ break;
+
default:
elog(ERROR, "unrecognized DISCARD target: %d", stmt->target);
}
@@ -75,4 +80,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 19f772a9fb6..eedce691bc0 100644
--- a/src/backend/commands/session_variable.c
+++ b/src/backend/commands/session_variable.c
@@ -94,7 +94,13 @@ pg_variable_cache_callback(Datum arg, int cacheid, uint32 hashvalue)
elog(DEBUG1, "pg_variable_cache_callback %u %u", cacheid, hashvalue);
- Assert(sessionvars);
+ /*
+ * There is no guarantee of session variables being initialized, even when
+ * receiving an invalidation callback, as DISCARD [ ALL | VARIABLES ]
+ * destroys the hash table entirely.
+ */
+ if (!sessionvars)
+ return;
/*
* If the hashvalue is not specified, we have to recheck all currently
@@ -658,3 +664,23 @@ pg_session_variables(PG_FUNCTION_ARGS)
return (Datum) 0;
}
+
+/*
+ * 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 VARIABLES (and DISCARD ALL) command.
+ */
+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/backend/parser/gram.y b/src/backend/parser/gram.y
index eeffa561731..929e340ac48 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -2096,7 +2096,13 @@ DiscardStmt:
n->target = DISCARD_SEQUENCES;
$$ = (Node *) n;
}
+ | DISCARD VARIABLES
+ {
+ DiscardStmt *n = makeNode(DiscardStmt);
+ n->target = DISCARD_VARIABLES;
+ $$ = (Node *) n;
+ }
;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index bdac691af13..84415f0caa1 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -2959,6 +2959,9 @@ CreateCommandTag(Node *parsetree)
case DISCARD_SEQUENCES:
tag = CMDTAG_DISCARD_SEQUENCES;
break;
+ case DISCARD_VARIABLES:
+ tag = CMDTAG_DISCARD_VARIABLES;
+ break;
default:
tag = CMDTAG_UNKNOWN;
}
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 172a37ed760..deb9563a598 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -4083,7 +4083,7 @@ match_previous_words(int pattern_id,
/* DISCARD */
else if (Matches("DISCARD"))
- COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP");
+ COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP", "VARIABLES");
/* DO */
else if (Matches("DO"))
diff --git a/src/include/commands/session_variable.h b/src/include/commands/session_variable.h
index b3f03c65827..443afbafd4a 100644
--- a/src/include/commands/session_variable.h
+++ b/src/include/commands/session_variable.h
@@ -29,4 +29,6 @@ extern Datum GetSessionVariableWithTypeCheck(Oid varid, bool *isNull, Oid expect
extern void ExecuteLetStmt(ParseState *pstate, LetStmt *stmt, ParamListInfo params,
QueryEnvironment *queryEnv, QueryCompletion *qc);
+extern void ResetSessionVariables(void);
+
#endif
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 20ed8394c78..781db0bb303 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -3977,6 +3977,7 @@ typedef enum DiscardMode
DISCARD_PLANS,
DISCARD_SEQUENCES,
DISCARD_TEMP,
+ DISCARD_VARIABLES,
} DiscardMode;
typedef struct DiscardStmt
diff --git a/src/include/tcop/cmdtaglist.h b/src/include/tcop/cmdtaglist.h
index a921af2486f..bd7964aea6e 100644
--- a/src/include/tcop/cmdtaglist.h
+++ b/src/include/tcop/cmdtaglist.h
@@ -135,6 +135,7 @@ PG_CMDTAG(CMDTAG_DISCARD_ALL, "DISCARD ALL", false, false, false)
PG_CMDTAG(CMDTAG_DISCARD_PLANS, "DISCARD PLANS", false, false, false)
PG_CMDTAG(CMDTAG_DISCARD_SEQUENCES, "DISCARD SEQUENCES", false, false, false)
PG_CMDTAG(CMDTAG_DISCARD_TEMP, "DISCARD TEMP", false, false, false)
+PG_CMDTAG(CMDTAG_DISCARD_VARIABLES, "DISCARD VARIABLES", false, false, false)
PG_CMDTAG(CMDTAG_DO, "DO", false, false, false)
PG_CMDTAG(CMDTAG_DROP_ACCESS_METHOD, "DROP ACCESS METHOD", true, false, false)
PG_CMDTAG(CMDTAG_DROP_AGGREGATE, "DROP AGGREGATE", true, false, false)
diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out
index 16e1d01ddc6..bcc8c8d847d 100644
--- a/src/test/regress/expected/session_variables.out
+++ b/src/test/regress/expected/session_variables.out
@@ -977,3 +977,66 @@ DROP VARIABLE :"DBNAME".:"DBNAME".b;
DROP VARIABLE :"DBNAME".:"DBNAME".:"DBNAME";
DROP SCHEMA :"DBNAME";
RESET search_path;
+-- memory cleaning by DISCARD command
+CREATE VARIABLE var1 AS varchar;
+LET var1 = 'Hello';
+SELECT var1;
+ var1
+-------
+ Hello
+(1 row)
+
+DISCARD ALL;
+SELECT var1;
+ var1
+------
+
+(1 row)
+
+LET var1 = 'AHOJ';
+SELECT var1;
+ var1
+------
+ AHOJ
+(1 row)
+
+DISCARD VARIABLES;
+SELECT var1;
+ var1
+------
+
+(1 row)
+
+DROP VARIABLE var1;
+-- initial test of debug pg_session_variables function
+-- should be zero now
+DISCARD VARIABLES;
+SELECT count(*) FROM pg_session_variables();
+ count
+-------
+ 0
+(1 row)
+
+CREATE VARIABLE var1 AS varchar;
+-- should be zero still
+SELECT count(*) FROM pg_session_variables();
+ count
+-------
+ 0
+(1 row)
+
+LET var1 = 'AHOJ';
+SELECT name, typname, can_select, can_update FROM pg_session_variables();
+ name | typname | can_select | can_update
+------+-------------------+------------+------------
+ var1 | character varying | t | t
+(1 row)
+
+DISCARD VARIABLES;
+-- should be zero again
+SELECT count(*) FROM pg_session_variables();
+ count
+-------
+ 0
+(1 row)
+
diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql
index d5bb5dc83be..d4165f34ffa 100644
--- a/src/test/regress/sql/session_variables.sql
+++ b/src/test/regress/sql/session_variables.sql
@@ -696,3 +696,39 @@ DROP VARIABLE :"DBNAME".:"DBNAME".:"DBNAME";
DROP SCHEMA :"DBNAME";
RESET search_path;
+
+-- memory cleaning by DISCARD command
+CREATE VARIABLE var1 AS varchar;
+LET var1 = 'Hello';
+SELECT var1;
+
+DISCARD ALL;
+SELECT var1;
+
+LET var1 = 'AHOJ';
+SELECT var1;
+
+DISCARD VARIABLES;
+SELECT var1;
+
+DROP VARIABLE var1;
+
+-- initial test of debug pg_session_variables function
+-- should be zero now
+DISCARD VARIABLES;
+
+SELECT count(*) FROM pg_session_variables();
+
+CREATE VARIABLE var1 AS varchar;
+
+-- should be zero still
+SELECT count(*) FROM pg_session_variables();
+
+LET var1 = 'AHOJ';
+
+SELECT name, typname, can_select, can_update FROM pg_session_variables();
+
+DISCARD VARIABLES;
+
+-- should be zero again
+SELECT count(*) FROM pg_session_variables();
--
2.47.0
view thread (439+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
Subject: Re: proposal: schema variables
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox