Re: [HACKERS] \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless) - Mailing list pgsql-hackers

From Tom Lane
Subject Re: [HACKERS] \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)
Date
Msg-id 30537.1489761433@sss.pgh.pa.us
Whole thread Raw
In response to Re: [HACKERS] \if, \elseif, \else, \endif (was Re: PSQL commands:\quit_if, \quit_unless)  (Fabien COELHO <coelho@cri.ensmp.fr>)
Responses Re: [HACKERS] \if, \elseif, \else, \endif (was Re: PSQL commands:\quit_if, \quit_unless)
List pgsql-hackers
Fabien COELHO <coelho@cri.ensmp.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



pgsql-hackers by date:

Previous
From: David Steele
Date:
Subject: Re: [HACKERS] PATCH: Make pg_stop_backup() archive wait optional
Next
From: Michael Meskes
Date:
Subject: Re: [HACKERS] Two phase commit in ECPG