Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Fabien COELHO <coelho(at)cri(dot)ensmp(dot)fr>
Cc: Corey Huinker <corey(dot)huinker(at)gmail(dot)com>, Daniel Verite <daniel(at)manitou-mail(dot)org>, "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, Greg Stark <stark(at)mit(dot)edu>, Erik Rijkers <er(at)xs4all(dot)nl>, Robert Haas <robertmhaas(at)gmail(dot)com>, Jim Nasby <Jim(dot)Nasby(at)bluetreble(dot)com>, PostgreSQL <pgsql-hackers(at)postgresql(dot)org>, pgsql-hackers-owner(at)postgresql(dot)org
Subject: Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)
Date: 2017-03-17 14:37:13
Message-ID: 30537.1489761433@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Fabien COELHO <coelho(at)cri(dot)ensmp(dot)fr> writes:
> ISTM that I've tried to suggest to work around that complexity by:
> - document that \if-related commands should only occur at line start
> (and extend to eol).
> - detect and complain when this is not the case.

I think this is a lousy definition, and would never be considered if we
were working in a green field. Moreover, preventing such cases would be
pretty darn ugly/messy as well.

I also fear that there are corner cases where the behavior would still
be inconsistent. Consider

\if ...
\set foo `echo \endif should not appear here`

If the \if succeeds, the result of the second line would be to set foo
to "endif should not appear here" (and we'd remain in the \if block).
But if the \if fails and we need to skip the \set command, any approach
that involves changing the argument parsing rules will fail to recognize
the backtick construct, and then will see the \endif as a command.
Similar examples can be constructed using \copy.

It's possible that we could keep the implementation that uses an early exit
from exec_command() if we were to move argument collection for all
backslash commands up to the start of the function. It would still be
a bit invasive, but perhaps not too awful: I'm imagining that instead of

else if (strcmp(cmd, "setenv") == 0)
{
char *envvar = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, false);
char *envval = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, false);

we'd write

else if (strcmp(cmd, "setenv") == 0)
{
char *envvar = args[0];
char *envval = args[1];

where the args array had been filled at the top of the function.
The top-of-function code would have to know all the cases where
commands didn't use basic OT_NORMAL processing, but there aren't
that many of those, I think.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Meskes 2017-03-17 14:50:48 Re: Two phase commit in ECPG
Previous Message David Steele 2017-03-17 14:31:56 Re: PATCH: Make pg_stop_backup() archive wait optional