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

From: Fabien COELHO <coelho(at)cri(dot)ensmp(dot)fr>
To: Corey Huinker <corey(dot)huinker(at)gmail(dot)com>
Cc: Daniel Verite <daniel(at)manitou-mail(dot)org>, PostgreSQL <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: \if, \elseif, \else, \endif (was Re: PSQL commands: \quit_if, \quit_unless)
Date: 2017-01-29 08:35:50
Message-ID: alpine.DEB.2.20.1701290916420.13068@lancre
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


Hello,

>> I'm wondering what pg would do on "EXISTS(SELECT 1 FROM customer)" if
>> there are many employees. [...]
>
> I believe that the scan stops on the first row it finds, because the
> EXITS() clause is met.

Hmmm... That is not so clear from "EXPLAIN" output:

Result (cost=0.03..0.04 rows=1 width=1)
InitPlan 1 (returns $0)
-> Seq Scan on ... (cost=0.00..263981.69 rows=10001769 width=0)

There is a plan for the sub-query, so it looks like it is actually fully
executed. Maybe adding "LIMIT 1" would be better?

> But it's not relevant to the documentation, I simply wanted to
> demonstrate some results that couldn't be resolved at parse time, so
> that the \if tests were meaningful. If the query example is distracting
> from the point of the documentation, we should change it.

My point is that examples about one thing can be interpreted as example
for other things which is also done in the example, so it is better to do
everything right.

>> In "read_boolean_expression": [...]

> This is code lifted from variable.c's ParseVariableBool(). When the other
> patch for "psql hooks" is committed (the one that detects when the string
> wasn't a valid boolean), this code will go away and we'll just use
> ParseVariableBool() again.

Hmmm. Copy-pasting is bad enough, and "when the other patch is committed"
is an unknown, so I would still suggest to fix obvious defects at least
(eg dead code which may result in compiler warnings, inconsistent
comments...).

>> [...] The second test on success may not rely on the value set above.
>> That looks very strange. ISTM that the state should be pushed whether
>> parsing succeeded or not. Moreover, it results in:
>>
>> \if ERROR
>> \echo X
>> \else
>> \echo Y
>> \endif
>>
>> having both X & Y printed and error reported on else and endif. I think
>> that an expression error should just put the stuff in ignore state.
>
> Not just false, but ignore the whole if-endif? interesting. I hadn't
> thought of that. Can do.

My point was that you must at least push something, otherwise both
branches are executed (!), and some commands could be attached to
upper-level conditions:

\if true
\if ERROR
...
\endif // this becomes "if true \endif"
...
\endif // this becomes an error

As for which state is pushed, it is indeed debatable. I do think that
pushing ignore on errors is a better/less risky behavior, but other
people' opinion may differ.

>> On "else" when in state ignored, ISTM that it should remain in state
>> ignore, not switch to else-false.
>
> That's how I know if this is the first "else" I encountered.

Ok, my mistake. Maybe expand the comment a little bit if appropriate.

>> History saving: I'm wondering whether all read line should be put into
>> history, whether executed or not.
>
> Good question. I gave it some thought and I decided it shouldn't. First,
> because history is a set of statements that were attempted, and those
> statements were not. But perhaps more importantly, because the statement
> could have contained an expandable variable, and since that variable would
> not be evaluated the SQL stored would be subtly altered from the original
> intent, perhaps in ways that might drastically alter the meaning of the
> statement. A highly contrived example:
>
> \set clause 'where cust_id = 1'
> \if false
> delete from customers :clause;
> \endif

Hmmm.

> So yeah, it just seemed easier to not store in history.

Hmmm.

As I recall, history is only for interactive mode. If I really typed
something, I'm expecting to get it by visiting previous commands, because
I certainly do not want to retype it again.

For your above example, maybe I would reedit the clause definition,
then want to execute the delete.

--
Fabien.

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Mithun Cy 2017-01-29 09:13:47 Re: Cache Hash Index meta page.
Previous Message Fabien COELHO 2017-01-29 08:15:34 Re: pgbench - allow to store select results into variables