aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-12-20 13:17:58 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2021-12-20 13:17:58 -0500
commit33d3eeadb21d2268104840cfef6bc2226ddfc680 (patch)
treecdbb296b2e765b889084f9d4fd32d4e50c23ae90
parent911588a3f816d875261d8f7d89e2517978831cd5 (diff)
downloadpostgresql-33d3eeadb21d2268104840cfef6bc2226ddfc680.tar.gz
postgresql-33d3eeadb21d2268104840cfef6bc2226ddfc680.zip
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
-rw-r--r--doc/src/sgml/ref/psql-ref.sgml22
-rw-r--r--src/bin/psql/command.c41
-rw-r--r--src/test/regress/expected/psql.out12
-rw-r--r--src/test/regress/sql/psql.sql12
4 files changed, 87 insertions, 0 deletions
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 48248f750e5..ae38d3dcc3e 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2238,6 +2238,28 @@ Tue Oct 26 21:40:57 CEST 1999
<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>
<listitem>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index ccd7b481084..fb3bab94948 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -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);
@@ -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)
@@ -1482,6 +1486,43 @@ exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
}
/*
+ * \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
*/
static backslashResult
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 930ce8597a1..6428ebc507d 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -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
diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
index e9d504baf21..d4e4fdbbb75 100644
--- a/src/test/regress/sql/psql.sql
+++ b/src/test/regress/sql/psql.sql
@@ -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