Skip to content

Commit 33d3eea

Browse files
committed
Add a \getenv command to psql.
\getenv fetches the value of an environment variable into a psql variable. This is the inverse of the \setenv command that was added over ten years ago. We'd not seen a compelling use-case for \getenv at the time, but upcoming regression test refactoring provides a sufficient reason to add it now. Discussion: https://postgr.es/m/1655733.1639871614@sss.pgh.pa.us
1 parent 911588a commit 33d3eea

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

doc/src/sgml/ref/psql-ref.sgml

+22
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,28 @@ Tue Oct 26 21:40:57 CEST 1999
22372237
</varlistentry>
22382238

22392239

2240+
<varlistentry>
2241+
<term><literal>\getenv <replaceable class="parameter">psql_var</replaceable> <replaceable class="parameter">env_var</replaceable></literal></term>
2242+
2243+
<listitem>
2244+
<para>
2245+
Gets the value of the environment
2246+
variable <replaceable class="parameter">env_var</replaceable>
2247+
and assigns it to the <application>psql</application>
2248+
variable <replaceable class="parameter">psql_var</replaceable>.
2249+
If <replaceable class="parameter">env_var</replaceable> is
2250+
not defined in the <application>psql</application> process's
2251+
environment, <replaceable class="parameter">psql_var</replaceable>
2252+
is not changed. Example:
2253+
<programlisting>
2254+
=&gt; <userinput>\getenv home HOME</userinput>
2255+
=&gt; <userinput>\echo :home</userinput>
2256+
/home/postgres
2257+
</programlisting></para>
2258+
</listitem>
2259+
</varlistentry>
2260+
2261+
22402262
<varlistentry>
22412263
<term><literal>\gexec</literal></term>
22422264

src/bin/psql/command.c

+41
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ static backslashResult process_command_g_options(char *first_option,
9898
bool active_branch,
9999
const char *cmd);
100100
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch);
101+
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch,
102+
const char *cmd);
101103
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch);
102104
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch);
103105
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch);
@@ -348,6 +350,8 @@ exec_command(const char *cmd,
348350
status = exec_command_g(scan_state, active_branch, cmd);
349351
else if (strcmp(cmd, "gdesc") == 0)
350352
status = exec_command_gdesc(scan_state, active_branch);
353+
else if (strcmp(cmd, "getenv") == 0)
354+
status = exec_command_getenv(scan_state, active_branch, cmd);
351355
else if (strcmp(cmd, "gexec") == 0)
352356
status = exec_command_gexec(scan_state, active_branch);
353357
else if (strcmp(cmd, "gset") == 0)
@@ -1481,6 +1485,43 @@ exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
14811485
return status;
14821486
}
14831487

1488+
/*
1489+
* \getenv -- set variable from environment variable
1490+
*/
1491+
static backslashResult
1492+
exec_command_getenv(PsqlScanState scan_state, bool active_branch,
1493+
const char *cmd)
1494+
{
1495+
bool success = true;
1496+
1497+
if (active_branch)
1498+
{
1499+
char *myvar = psql_scan_slash_option(scan_state,
1500+
OT_NORMAL, NULL, false);
1501+
char *envvar = psql_scan_slash_option(scan_state,
1502+
OT_NORMAL, NULL, false);
1503+
1504+
if (!myvar || !envvar)
1505+
{
1506+
pg_log_error("\\%s: missing required argument", cmd);
1507+
success = false;
1508+
}
1509+
else
1510+
{
1511+
char *envval = getenv(envvar);
1512+
1513+
if (envval && !SetVariable(pset.vars, myvar, envval))
1514+
success = false;
1515+
}
1516+
free(myvar);
1517+
free(envvar);
1518+
}
1519+
else
1520+
ignore_slash_options(scan_state);
1521+
1522+
return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
1523+
}
1524+
14841525
/*
14851526
* \gexec -- send query and execute each field of result
14861527
*/

src/test/regress/expected/psql.out

+12
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,18 @@ select '2000-01-01'::date as party_over
282282
(1 row)
283283

284284
\unset FETCH_COUNT
285+
-- \setenv, \getenv
286+
-- ensure MYVAR isn't set
287+
\setenv MYVAR
288+
-- in which case, reading it doesn't change the target
289+
\getenv res MYVAR
290+
\echo :res
291+
:res
292+
-- now set it
293+
\setenv MYVAR 'environment value'
294+
\getenv res MYVAR
295+
\echo :res
296+
environment value
285297
-- show all pset options
286298
\pset
287299
border 1

src/test/regress/sql/psql.sql

+12
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over'
141141

142142
\unset FETCH_COUNT
143143

144+
-- \setenv, \getenv
145+
146+
-- ensure MYVAR isn't set
147+
\setenv MYVAR
148+
-- in which case, reading it doesn't change the target
149+
\getenv res MYVAR
150+
\echo :res
151+
-- now set it
152+
\setenv MYVAR 'environment value'
153+
\getenv res MYVAR
154+
\echo :res
155+
144156
-- show all pset options
145157
\pset
146158

0 commit comments

Comments
 (0)