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
     \echo Y

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;


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


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.


Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:

Reply via email to