v20250929-0004-support-of-session-variables-for-psql.patch
text/x-patch
Filename: v20250929-0004-support-of-session-variables-for-psql.patch
Type: text/x-patch
Part: 11
Message:
Re: proposal: schema variables
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v20250929-0004
Subject: support of session variables for psql
| File | + | − |
|---|---|---|
| doc/src/sgml/func/func-info.sgml | 13 | 0 |
| doc/src/sgml/ref/psql-ref.sgml | 13 | 0 |
| src/backend/catalog/namespace.c | 14 | 0 |
| src/bin/psql/command.c | 3 | 0 |
| src/bin/psql/describe.c | 99 | 1 |
| src/bin/psql/describe.h | 3 | 0 |
| src/bin/psql/help.c | 1 | 0 |
| src/bin/psql/tab-complete.in.c | 39 | 6 |
| src/include/catalog/pg_proc.dat | 3 | 0 |
| src/test/regress/expected/psql.out | 50 | 0 |
| src/test/regress/sql/psql.sql | 21 | 0 |
From 31f8f057d08aa0742d4bc8ddcb2a205815463c97 Mon Sep 17 00:00:00 2001
From: "okbob@github.com" <pavel.stehule@gmail.com>
Date: Tue, 5 Aug 2025 06:42:02 +0200
Subject: [PATCH 04/15] support of session variables for psql
This patch enhancing psql to support session variables:
* \dV[+] command
* tab complete for CREATE, DROP, ALTER VARIABLE
Note: tab complete for variable fencing is not supported yet
---
doc/src/sgml/func/func-info.sgml | 13 ++++
doc/src/sgml/ref/psql-ref.sgml | 13 ++++
src/backend/catalog/namespace.c | 14 ++++
src/bin/psql/command.c | 3 +
src/bin/psql/describe.c | 100 ++++++++++++++++++++++++++++-
src/bin/psql/describe.h | 3 +
src/bin/psql/help.c | 1 +
src/bin/psql/tab-complete.in.c | 45 +++++++++++--
src/include/catalog/pg_proc.dat | 3 +
src/test/regress/expected/psql.out | 50 +++++++++++++++
src/test/regress/sql/psql.sql | 21 ++++++
11 files changed, 259 insertions(+), 7 deletions(-)
diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index a57f7665054..3aad9d0529f 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -1377,6 +1377,19 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
Is type (or domain) visible in search path?
</para></entry>
</row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_variable_is_visible</primary>
+ </indexterm>
+ <function>pg_variable_is_visible</function> ( <parameter>variable</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is session variable visible in search path?
+ </para></entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 1a339600bc4..6bb3a9dad50 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2144,6 +2144,19 @@ SELECT $1 \parse stmt1
</listitem>
</varlistentry>
+ <varlistentry id="app-psql-meta-command-dv">
+ <term><literal>\dV[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists session variables.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only session variables whose names match the pattern are listed.
+ If the form <literal>\dV+</literal> is used, additional information
+ about each variable is shown, like access privileges and description.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-psql-meta-command-du">
<term><literal>\du[Sx+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
<listitem>
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index df15852d906..338d78e174f 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -5359,3 +5359,17 @@ pg_is_other_temp_schema(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(isOtherTempNamespace(oid));
}
+
+Datum
+pg_variable_is_visible(PG_FUNCTION_ARGS)
+{
+ Oid oid = PG_GETARG_OID(0);
+ bool result;
+ bool is_missing = false;
+
+ result = VariableIsVisibleExt(oid, &is_missing);
+
+ if (is_missing)
+ PG_RETURN_NULL();
+ PG_RETURN_BOOL(result);
+}
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index cc602087db2..0ac7b9881cd 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1270,6 +1270,9 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
}
break;
+ case 'V': /* Variables */
+ success = listVariables(pattern, show_verbose);
+ break;
case 'x': /* Extensions */
if (show_verbose)
success = listExtensionContents(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 4aa793d7de7..1f5f7ced772 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1224,7 +1224,7 @@ listDefaultACLs(const char *pattern)
"SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
" n.nspname AS \"%s\",\n"
" CASE d.defaclobjtype "
- " WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s'"
+ " WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s'"
" WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
" ",
gettext_noop("Owner"),
@@ -1241,6 +1241,8 @@ listDefaultACLs(const char *pattern)
gettext_noop("schema"),
DEFACLOBJ_LARGEOBJECT,
gettext_noop("large object"),
+ DEFACLOBJ_VARIABLE,
+ gettext_noop("session variable"),
gettext_noop("Type"));
printACLColumn(&buf, "d.defaclacl");
@@ -5314,6 +5316,102 @@ error_return:
return false;
}
+/*
+ * \dV
+ *
+ * listVariables()
+ */
+bool
+listVariables(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+ static const bool translate_columns[] = {false, false, false, false, false, false, false};
+
+ if (pset.sversion < 180000)
+ {
+ char sverbuf[32];
+
+ pg_log_error("The server (version %s) does not support session variables.",
+ formatPGVersionNumber(pset.sversion, false,
+ sverbuf, sizeof(sverbuf)));
+ return true;
+ }
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT n.nspname as \"%s\",\n"
+ " v.varname as \"%s\",\n"
+ " pg_catalog.format_type(v.vartype, v.vartypmod) as \"%s\",\n"
+ " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
+ " WHERE c.oid = v.varcollation AND bt.oid = v.vartype AND v.varcollation <> bt.typcollation) as \"%s\",\n"
+ " pg_catalog.pg_get_userbyid(v.varowner) as \"%s\"\n",
+ gettext_noop("Schema"),
+ gettext_noop("Name"),
+ gettext_noop("Type"),
+ gettext_noop("Collation"),
+ gettext_noop("Owner"));
+
+ if (verbose)
+ {
+ appendPQExpBufferStr(&buf, ",\n ");
+ printACLColumn(&buf, "v.varacl");
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(v.oid, 'pg_variable') AS \"%s\"",
+ gettext_noop("Description"));
+ }
+
+ appendPQExpBufferStr(&buf,
+ "\nFROM pg_catalog.pg_variable v"
+ "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = v.varnamespace");
+
+ appendPQExpBufferStr(&buf, "\nWHERE true\n");
+ if (!pattern)
+ appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
+ " AND n.nspname <> 'information_schema'\n");
+
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "v.varname", NULL,
+ "pg_catalog.pg_variable_is_visible(v.oid)",
+ NULL, 3))
+ return false;
+
+ appendPQExpBufferStr(&buf, "ORDER BY 1,2;");
+
+ res = PSQLexec(buf.data);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ /*
+ * Most functions in this file are content to print an empty table when
+ * there are no matching objects. We intentionally deviate from that
+ * here, but only in !quiet mode, for historical reasons.
+ */
+ if (PQntuples(res) == 0 && !pset.quiet)
+ {
+ if (pattern)
+ pg_log_error("Did not find any session variable named \"%s\".",
+ pattern);
+ else
+ pg_log_error("Did not find any session variables.");
+ }
+ else
+ {
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of variables");
+ myopt.translate_header = true;
+ myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
+
+ printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
+ }
+
+ PQclear(res);
+ return true;
+}
/*
* \dFp
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 18ecaa60949..55ced4aab7b 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -149,4 +149,7 @@ extern bool listOpFamilyFunctions(const char *access_method_pattern,
/* \dl or \lo_list */
extern bool listLargeObjects(bool verbose);
+/* \dV */
+extern bool listVariables(const char *pattern, bool varbose);
+
#endif /* DESCRIBE_H */
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index ed00c36695e..aa91a7ce10f 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -266,6 +266,7 @@ slashUsage(unsigned short int pager)
HELP0(" \\dT[Sx+] [PATTERN] list data types\n");
HELP0(" \\du[Sx+] [PATTERN] list roles\n");
HELP0(" \\dv[Sx+] [PATTERN] list views\n");
+ HELP0(" \\dV[x+] [PATTERN] list session variables\n");
HELP0(" \\dx[x+] [PATTERN] list extensions\n");
HELP0(" \\dX[x] [PATTERN] list extended statistics\n");
HELP0(" \\dy[x+] [PATTERN] list event triggers\n");
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 6176741d20b..5fc5c15057b 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -988,6 +988,13 @@ static const SchemaQuery Query_for_trigger_of_table = {
.refnamespace = "c1.relnamespace",
};
+static const SchemaQuery Query_for_list_of_variables = {
+ .min_server_version = 180000,
+ .catname = "pg_catalog.pg_variable v",
+ .viscondition = "pg_catalog.pg_variable_is_visible(v.oid)",
+ .namespace = "v.varnamespace",
+ .result = "v.varname",
+};
/*
* Queries to get lists of names of various kinds of things, possibly
@@ -1352,6 +1359,7 @@ static const pgsql_thing_t words_after_create[] = {
* TABLE ... */
{"USER", Query_for_list_of_roles, NULL, NULL, Keywords_for_user_thing},
{"USER MAPPING FOR", NULL, NULL, NULL},
+ {"VARIABLE", NULL, NULL, &Query_for_list_of_variables},
{"VIEW", NULL, NULL, &Query_for_list_of_views},
{NULL} /* end of list */
};
@@ -1917,7 +1925,7 @@ psql_completion(const char *text, int start, int end)
"\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL",
"\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt",
"\\drds", "\\drg", "\\dRs", "\\dRp", "\\ds",
- "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dX", "\\dy",
+ "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dX", "\\dy", "\\dV",
"\\echo", "\\edit", "\\ef", "\\elif", "\\else", "\\encoding",
"\\endif", "\\endpipeline", "\\errverbose", "\\ev",
"\\f", "\\flush", "\\flushrequest",
@@ -2631,6 +2639,9 @@ match_previous_words(int pattern_id,
"ALL");
else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
COMPLETE_WITH("TO");
+ /* ALTER VARIABLE <name> */
+ else if (Matches("ALTER", "VARIABLE", MatchAny))
+ COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA");
/* ALTER VIEW <name> */
else if (Matches("ALTER", "VIEW", MatchAny))
COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME", "RESET", "SET");
@@ -3237,7 +3248,7 @@ match_previous_words(int pattern_id,
"ROUTINE", "RULE", "SCHEMA", "SEQUENCE", "SERVER",
"STATISTICS", "SUBSCRIPTION", "TABLE",
"TABLESPACE", "TEXT SEARCH", "TRANSFORM FOR",
- "TRIGGER", "TYPE", "VIEW");
+ "TRIGGER", "TYPE", "VARIABLE", "VIEW");
else if (Matches("COMMENT", "ON", "ACCESS", "METHOD"))
COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
else if (Matches("COMMENT", "ON", "CONSTRAINT"))
@@ -4043,6 +4054,13 @@ match_previous_words(int pattern_id,
else if (TailMatches("=", MatchAnyExcept("*)")))
COMPLETE_WITH(",", ")");
}
+/* CREATE VARIABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */
+ /* Complete CREATE VARIABLE <name> with AS */
+ else if (TailMatches("CREATE", "VARIABLE", MatchAny))
+ COMPLETE_WITH("AS");
+ else if (TailMatches("VARIABLE", MatchAny, "AS"))
+ /* Complete CREATE VARIABLE <name> with AS types */
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
/* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */
/* Complete CREATE [ OR REPLACE ] VIEW <name> with AS or WITH */
@@ -4320,6 +4338,12 @@ match_previous_words(int pattern_id,
else if (Matches("DROP", "TRANSFORM", "FOR", MatchAny, "LANGUAGE", MatchAny))
COMPLETE_WITH("CASCADE", "RESTRICT");
+ /* DROP VARIABLE */
+ else if (Matches("DROP", "VARIABLE"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_variables);
+ else if (Matches("DROP", "VARIABLE", MatchAny))
+ COMPLETE_WITH("CASCADE", "RESTRICT");
+
/* EXECUTE */
else if (Matches("EXECUTE"))
COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
@@ -4521,7 +4545,9 @@ match_previous_words(int pattern_id,
* objects supported.
*/
if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
- COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS", "LARGE OBJECTS");
+ COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES",
+ "ROUTINES", "TYPES", "SCHEMAS", "LARGE OBJECTS",
+ "VARIABLES");
else
COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_grantables,
"ALL FUNCTIONS IN SCHEMA",
@@ -4529,6 +4555,7 @@ match_previous_words(int pattern_id,
"ALL ROUTINES IN SCHEMA",
"ALL SEQUENCES IN SCHEMA",
"ALL TABLES IN SCHEMA",
+ "ALL VARIABLES IN SCHEMA",
"DATABASE",
"DOMAIN",
"FOREIGN DATA WRAPPER",
@@ -4543,7 +4570,8 @@ match_previous_words(int pattern_id,
"SEQUENCE",
"TABLE",
"TABLESPACE",
- "TYPE");
+ "TYPE",
+ "VARIABLE");
}
else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL") ||
TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "ALL"))
@@ -4551,7 +4579,8 @@ match_previous_words(int pattern_id,
"PROCEDURES IN SCHEMA",
"ROUTINES IN SCHEMA",
"SEQUENCES IN SCHEMA",
- "TABLES IN SCHEMA");
+ "TABLES IN SCHEMA",
+ "VARIABLES IN SCHEMA");
else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN") ||
TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny, "ON", "FOREIGN"))
COMPLETE_WITH("DATA WRAPPER", "SERVER");
@@ -4587,6 +4616,8 @@ match_previous_words(int pattern_id,
COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
else if (TailMatches("TYPE"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
+ else if (TailMatches("VARIABLE"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_variables);
else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny))
COMPLETE_WITH("TO");
else
@@ -4913,7 +4944,7 @@ match_previous_words(int pattern_id,
/* PREPARE xx AS */
else if (Matches("PREPARE", MatchAny, "AS"))
- COMPLETE_WITH("SELECT", "UPDATE", "INSERT INTO", "DELETE FROM");
+ COMPLETE_WITH("SELECT", "UPDATE", "INSERT INTO", "DELETE FROM", "LET");
/*
* PREPARE TRANSACTION is missing on purpose. It's intended for transaction
@@ -5402,6 +5433,8 @@ match_previous_words(int pattern_id,
COMPLETE_WITH_QUERY(Query_for_list_of_roles);
else if (TailMatchesCS("\\dv*"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views);
+ else if (TailMatchesCS("\\dV*"))
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_variables);
else if (TailMatchesCS("\\dx*"))
COMPLETE_WITH_QUERY(Query_for_list_of_extensions);
else if (TailMatchesCS("\\dX*"))
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index e5b48d3530d..d28fb3283cb 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6709,6 +6709,9 @@
proname => 'pg_collation_is_visible', procost => '10', provolatile => 's',
prorettype => 'bool', proargtypes => 'oid',
prosrc => 'pg_collation_is_visible' },
+{ oid => '9999', descr => 'is session variable visible in search path?',
+ proname => 'pg_variable_is_visible', procost => '10', provolatile => 's',
+ prorettype => 'bool', proargtypes => 'oid', prosrc => 'pg_variable_is_visible' },
{ oid => '2854', descr => 'get OID of current session\'s temp schema, if any',
proname => 'pg_my_temp_schema', provolatile => 's', proparallel => 'r',
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index a79325e8a2f..f2e506796db 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -6025,6 +6025,30 @@ COMMIT;
# final ON_ERROR_ROLLBACK: off
DROP TABLE bla;
DROP FUNCTION psql_error;
+-- session variable test
+CREATE ROLE regress_variable_owner;
+SET ROLE TO regress_variable_owner;
+CREATE VARIABLE var1 AS varchar COLLATE "C";
+\dV+ var1
+ List of variables
+ Schema | Name | Type | Collation | Owner | Access privileges | Description
+--------+------+-------------------+-----------+------------------------+-------------------+-------------
+ public | var1 | character varying | C | regress_variable_owner | |
+(1 row)
+
+GRANT SELECT ON VARIABLE var1 TO PUBLIC;
+COMMENT ON VARIABLE var1 IS 'some description';
+\dV+ var1
+ List of variables
+ Schema | Name | Type | Collation | Owner | Access privileges | Description
+--------+------+-------------------+-----------+------------------------+--------------------------------------------------+------------------
+ public | var1 | character varying | C | regress_variable_owner | regress_variable_owner=rw/regress_variable_owner+| some description
+ | | | | | =r/regress_variable_owner |
+(1 row)
+
+DROP VARIABLE var1;
+SET ROLE TO DEFAULT;
+DROP ROLE regress_variable_owner;
-- check describing invalid multipart names
\dA regression.heap
improper qualified name (too many dotted names): regression.heap
@@ -6246,6 +6270,12 @@ cross-database references are not implemented: nonesuch.public.func_deps_stat
improper qualified name (too many dotted names): regression.myevt
\dy nonesuch.myevt
improper qualified name (too many dotted names): nonesuch.myevt
+\dV host.regression.public.var
+improper qualified name (too many dotted names): host.regression.public.var
+\dV regression|mydb.public.var
+cross-database references are not implemented: regression|mydb.public.var
+\dV nonesuch.public.var
+cross-database references are not implemented: nonesuch.public.var
-- check that dots within quoted name segments are not counted
\dA "no.such.access.method"
List of access methods
@@ -6480,6 +6510,12 @@ List of schemas
------+-------+-------+---------+----------+------
(0 rows)
+\dV "no.such.variable"
+ List of variables
+ Schema | Name | Type | Collation | Owner
+--------+------+------+-----------+-------
+(0 rows)
+
-- again, but with dotted schema qualifications.
\dA "no.such.schema"."no.such.access.method"
improper qualified name (too many dotted names): "no.such.schema"."no.such.access.method"
@@ -6649,6 +6685,12 @@ improper qualified name (too many dotted names): "no.such.schema"."no.such.insta
\dy "no.such.schema"."no.such.event.trigger"
improper qualified name (too many dotted names): "no.such.schema"."no.such.event.trigger"
+\dV "no.such.schema"."no.such.variable"
+ List of variables
+ Schema | Name | Type | Collation | Owner
+--------+------+------+-----------+-------
+(0 rows)
+
-- again, but with current database and dotted schema qualifications.
\dt regression."no.such.schema"."no.such.table.relation"
List of tables
@@ -6782,6 +6824,12 @@ List of text search templates
--------+------+------------+-----------+--------------+-----
(0 rows)
+\dV regression."no.such.schema"."no.such.variable"
+ List of variables
+ Schema | Name | Type | Collation | Owner
+--------+------+------+-----------+-------
+(0 rows)
+
-- again, but with dotted database and dotted schema qualifications.
\dt "no.such.database"."no.such.schema"."no.such.table.relation"
cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.table.relation"
@@ -6829,6 +6877,8 @@ cross-database references are not implemented: "no.such.database"."no.such.schem
cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.data.type"
\dX "no.such.database"."no.such.schema"."no.such.extended.statistics"
cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.extended.statistics"
+\dV "no.such.database"."no.such.schema"."no.such.variable"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.variable"
-- check \drg and \du
CREATE ROLE regress_du_role0;
CREATE ROLE regress_du_role1;
diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
index f064e4f5456..8f6108e44de 100644
--- a/src/test/regress/sql/psql.sql
+++ b/src/test/regress/sql/psql.sql
@@ -1645,6 +1645,19 @@ COMMIT;
DROP TABLE bla;
DROP FUNCTION psql_error;
+-- session variable test
+CREATE ROLE regress_variable_owner;
+SET ROLE TO regress_variable_owner;
+CREATE VARIABLE var1 AS varchar COLLATE "C";
+\dV+ var1
+GRANT SELECT ON VARIABLE var1 TO PUBLIC;
+COMMENT ON VARIABLE var1 IS 'some description';
+\dV+ var1
+DROP VARIABLE var1;
+
+SET ROLE TO DEFAULT;
+DROP ROLE regress_variable_owner;
+
-- check describing invalid multipart names
\dA regression.heap
\dA nonesuch.heap
@@ -1756,6 +1769,9 @@ DROP FUNCTION psql_error;
\dX nonesuch.public.func_deps_stat
\dy regression.myevt
\dy nonesuch.myevt
+\dV host.regression.public.var
+\dV regression|mydb.public.var
+\dV nonesuch.public.var
-- check that dots within quoted name segments are not counted
\dA "no.such.access.method"
@@ -1797,6 +1813,8 @@ DROP FUNCTION psql_error;
\dx "no.such.installed.extension"
\dX "no.such.extended.statistics"
\dy "no.such.event.trigger"
+\dV "no.such.variable"
+
-- again, but with dotted schema qualifications.
\dA "no.such.schema"."no.such.access.method"
@@ -1837,6 +1855,7 @@ DROP FUNCTION psql_error;
\dx "no.such.schema"."no.such.installed.extension"
\dX "no.such.schema"."no.such.extended.statistics"
\dy "no.such.schema"."no.such.event.trigger"
+\dV "no.such.schema"."no.such.variable"
-- again, but with current database and dotted schema qualifications.
\dt regression."no.such.schema"."no.such.table.relation"
@@ -1861,6 +1880,7 @@ DROP FUNCTION psql_error;
\dP regression."no.such.schema"."no.such.partitioned.relation"
\dT regression."no.such.schema"."no.such.data.type"
\dX regression."no.such.schema"."no.such.extended.statistics"
+\dV regression."no.such.schema"."no.such.variable"
-- again, but with dotted database and dotted schema qualifications.
\dt "no.such.database"."no.such.schema"."no.such.table.relation"
@@ -1886,6 +1906,7 @@ DROP FUNCTION psql_error;
\dP "no.such.database"."no.such.schema"."no.such.partitioned.relation"
\dT "no.such.database"."no.such.schema"."no.such.data.type"
\dX "no.such.database"."no.such.schema"."no.such.extended.statistics"
+\dV "no.such.database"."no.such.schema"."no.such.variable"
-- check \drg and \du
CREATE ROLE regress_du_role0;
--
2.51.0