diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-12-20 13:17:58 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-12-20 13:17:58 -0500 |
commit | 33d3eeadb21d2268104840cfef6bc2226ddfc680 (patch) | |
tree | cdbb296b2e765b889084f9d4fd32d4e50c23ae90 | |
parent | 911588a3f816d875261d8f7d89e2517978831cd5 (diff) | |
download | postgresql-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.sgml | 22 | ||||
-rw-r--r-- | src/bin/psql/command.c | 41 | ||||
-rw-r--r-- | src/test/regress/expected/psql.out | 12 | ||||
-rw-r--r-- | src/test/regress/sql/psql.sql | 12 |
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> +=> <userinput>\getenv home HOME</userinput> +=> <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 |