Skip to content

Commit

Permalink
Add a \getenv command to psql.
Browse files Browse the repository at this point in the history
\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
  • Loading branch information
tglsfdc committed Dec 20, 2021
1 parent 911588a commit 33d3eea
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
22 changes: 22 additions & 0 deletions doc/src/sgml/ref/psql-ref.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,28 @@ Tue Oct 26 21:40:57 CEST 1999
</varlistentry>


<varlistentry>
<term><literal>\getenv <replaceable class="parameter">psql_var</replaceable> <replaceable class="parameter">env_var</replaceable></literal></term>

<listitem>
<para>
Gets the value of the environment
variable <replaceable class="parameter">env_var</replaceable>
and assigns it to the <application>psql</application>
variable <replaceable class="parameter">psql_var</replaceable>.
If <replaceable class="parameter">env_var</replaceable> is
not defined in the <application>psql</application> process's
environment, <replaceable class="parameter">psql_var</replaceable>
is not changed. Example:
<programlisting>
=&gt; <userinput>\getenv home HOME</userinput>
=&gt; <userinput>\echo :home</userinput>
/home/postgres
</programlisting></para>
</listitem>
</varlistentry>


<varlistentry>
<term><literal>\gexec</literal></term>

Expand Down
41 changes: 41 additions & 0 deletions src/bin/psql/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ static backslashResult process_command_g_options(char *first_option,
bool active_branch,
const char *cmd);
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch,
const char *cmd);
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch);
Expand Down Expand Up @@ -348,6 +350,8 @@ exec_command(const char *cmd,
status = exec_command_g(scan_state, active_branch, cmd);
else if (strcmp(cmd, "gdesc") == 0)
status = exec_command_gdesc(scan_state, active_branch);
else if (strcmp(cmd, "getenv") == 0)
status = exec_command_getenv(scan_state, active_branch, cmd);
else if (strcmp(cmd, "gexec") == 0)
status = exec_command_gexec(scan_state, active_branch);
else if (strcmp(cmd, "gset") == 0)
Expand Down Expand Up @@ -1481,6 +1485,43 @@ exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
return status;
}

/*
* \getenv -- set variable from environment variable
*/
static backslashResult
exec_command_getenv(PsqlScanState scan_state, bool active_branch,
const char *cmd)
{
bool success = true;

if (active_branch)
{
char *myvar = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, false);
char *envvar = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, false);

if (!myvar || !envvar)
{
pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else
{
char *envval = getenv(envvar);

if (envval && !SetVariable(pset.vars, myvar, envval))
success = false;
}
free(myvar);
free(envvar);
}
else
ignore_slash_options(scan_state);

return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
}

/*
* \gexec -- send query and execute each field of result
*/
Expand Down
12 changes: 12 additions & 0 deletions src/test/regress/expected/psql.out
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,18 @@ select '2000-01-01'::date as party_over
(1 row)

\unset FETCH_COUNT
-- \setenv, \getenv
-- ensure MYVAR isn't set
\setenv MYVAR
-- in which case, reading it doesn't change the target
\getenv res MYVAR
\echo :res
:res
-- now set it
\setenv MYVAR 'environment value'
\getenv res MYVAR
\echo :res
environment value
-- show all pset options
\pset
border 1
Expand Down
12 changes: 12 additions & 0 deletions src/test/regress/sql/psql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over'

\unset FETCH_COUNT

-- \setenv, \getenv

-- ensure MYVAR isn't set
\setenv MYVAR
-- in which case, reading it doesn't change the target
\getenv res MYVAR
\echo :res
-- now set it
\setenv MYVAR 'environment value'
\getenv res MYVAR
\echo :res

-- show all pset options
\pset

Expand Down

0 comments on commit 33d3eea

Please sign in to comment.