Re: \if, \elseif, \else, \endif (was Re: [HACKERS] PSQL commands:\quit_if, \quit_unless) - Mailing list pgsql-hackers
From | Fabien COELHO |
---|---|
Subject | Re: \if, \elseif, \else, \endif (was Re: [HACKERS] PSQL commands:\quit_if, \quit_unless) |
Date | |
Msg-id | alpine.DEB.2.20.1701290916420.13068@lancre Whole thread Raw |
In response to | Re: \if, \elseif, \else, \endif (was Re: [HACKERS] PSQL commands:\quit_if, \quit_unless) (Corey Huinker <corey.huinker@gmail.com>) |
Responses |
Re: \if, \elseif, \else, \endif (was Re: [HACKERS] PSQL commands:\quit_if, \quit_unless)
Re: \if, \elseif, \else, \endif (was Re: [HACKERS] PSQL commands:\quit_if, \quit_unless) Re: \if, \elseif, \else, \endif (was Re: [HACKERS] PSQL commands:\quit_if, \quit_unless) |
List | 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=10001769width=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.
pgsql-hackers by date: