On Fri, Nov 13, 2015 at 1:54 PM, Catalin Iacob <iacobcata...@gmail.com> wrote:
> So I promised I'd try to document this. I had a look at the proposed > semantics of -C and I think in the patch they're too complicated which > makes explaining them hard. > > My assumptions about behaviour without this patch, from reading the > docs and some experimenting, correct me if I'm wrong: > > 1. psql normally splits its input by ; let's call each piece of the > split a statement > > 2. for every statement resulting after 1, if it's a \ command it's > interpreted internally, else a query with it is sent to the server, > the result is displayed > > 3. 1. and 2. happen when the input comes from a file (-f) or from stdin > > 4. autocommit off changes behaviour in that it sends a BEGIN before > any of the statements after the split in 1 (except for \ commands, > BEGIN or things like VACUUM which don't work within transactions) > > 5. --single-transaction changes behaviour in that it puts a BEGIN > before the whole input (not around each statement) and a COMMIT after > > 6. all of the above DON'T apply for -c which very different things: it > doesn't split and instead it sends everything, in one query to the > backend. The backend can execute such a thing (it splits itself by ;) > except in some cases like SELECT + VACUUM. Since the single query is > effectively a single transaction for the backend -c ignores > --single-transaction and autocommit off. Even more, when executing > such a multiple statement the backend only returns results for the > last statement of the query. > > From the above it seems -c is a different thing altogether while other > behaviour allows 1 input with multiple commands, multiple results and > works the same on stdin and a file. > > So my proposal is: allow a *single* argument for -C and treat its > content *exactly* like the input from stdin or from a file. > > This answers all the questions about interactions with > --single-transaction and autocommit naturally: it behaves exactly like > stdin and -f behave today. And having a single parameter is similar to > having a single file or single stdin. Having multiple -C is also > confusing since it seems the statements in one -C are grouped somehow > and the ones in the next -C are another group so this starts feeling > like there's maybe a transaction per -C group etc. > > Am I missing something or is it that simple? > While not in patch form here is some food for thought. Tweaks to -c to link it with -C 6c6 < Specifies that <application>psql</application> is to execute one --- > Specifies that <application>psql</application> is to execute the 12d11 < <para> 32a32,36 > Furthermore, only a single instance of this parameter is accepted. > Attempting to provide multiple instances will result in the entire > shell command failing. > </para> > <para> 34,35c38,41 < the <option>-c</option> string often has unexpected results. It's < better to feed multiple commands to <application>psql</application>'s --- > the <option>-c</option> string often has unexpected results. Two > better options are available to execute multiple commands in a > controlled manner. You may use the -C option, described next, or > choose to feed multiple commands to <application>psql</application>'s Draft -C thoughts <term><option>-C <replaceable class="parameter">command(s)</replaceable></></term> <term><option>--multi-command=<replaceable class="parameter">command(s)</replaceable></></term> <listitem> <para> Specifies that <application>psql</application> is to execute one or more command strings, <replaceable class="parameter">commands</replaceable>, and then exit. This differs from -c in that multiple instances may be present on the same shell command. </para> <para> Also unlike -c, individual <option>-C</option> commands and statements are executed in auto-commit mode. The following pseudo-code example describe the script that is effectively created. </para> <programlisting> psql -C 'SELECT 1;SELECT 2' -C 'SELECT 3;SELECT4' psql <<EOF BEGIN; SELECT 1; COMMIT; BEGIN; SELECT 2; COMMIT; BEGIN; SELECT 3; COMMIT; BEGIN; SELECT 4; COMMIT; EOF </programlisting> <para> Alternatively the option <option>--single-transaction</option> makes the entire multi-command execute within a single transaction. There is no option to have entire <option>-C</option> commands commit independently of each other; you have to issue separate psql shell commands. </para> <para> Output from the <option>-C</option> command behaves more script-like than <option>-c</option> as each statement within each command is output. </para> <para> As with <option>-c</option> the Start-up files (<filename>psqlrc</filename> and <filename>~/.psqlrc</filename>) are ignored if this option is present on the command-line. </para> <para> One particular motivation for introducing <option>-C</option> is the first command below fails if executed using <option>-c</option> but now there are two equivalent command lines that work. <programlisting> psql -Atq -C "VACUUM FULL foo; SELECT pg_relation_size('foo')" psql -Atq -C "VACUUM FULL foo" -C "SELECT pg_relation_size('foo')" </programlisting> </para>