diff options
-rw-r--r-- | doc/src/sgml/ref/psql-ref.sgml | 10 | ||||
-rw-r--r-- | src/bin/psql/command.c | 2 | ||||
-rw-r--r-- | src/bin/psql/common.c | 32 |
3 files changed, 27 insertions, 17 deletions
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 4c87d8ad7fe..eb5e3b19048 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1608,9 +1608,13 @@ Tue Oct 26 21:40:57 CEST 1999 optionally stores the query's output in <replaceable class="parameter">filename</replaceable> or pipes the output into a separate Unix shell executing <replaceable - class="parameter">command</replaceable>. A bare - <literal>\g</literal> is virtually equivalent to a semicolon. A - <literal>\g</literal> with argument is a <quote>one-shot</quote> + class="parameter">command</replaceable>. The file or command is + written to only if the query successfully returns zero or more tuples, + not if the query fails or is a non-data-returning SQL command. + </para> + <para> + A bare <literal>\g</literal> is essentially equivalent to a semicolon. + A <literal>\g</literal> with argument is a <quote>one-shot</quote> alternative to the <command>\o</command> command. </para> </listitem> diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 20c45e2d0a5..1e9aa89089e 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -731,7 +731,7 @@ exec_command(const char *cmd, free(fname); } - /* \g means send query */ + /* \g [filename] means send query, optionally with output to file/pipe */ else if (strcmp(cmd, "g") == 0) { char *fname = psql_scan_slash_option(scan_state, diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 5fb031650e3..ab517906fca 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -607,9 +607,6 @@ PrintQueryTuples(const PGresult *results) pset.queryFout = queryFout_copy; pset.queryFoutPipe = queryFoutPipe_copy; - - free(pset.gfname); - pset.gfname = NULL; } else printQuery(results, &my_popt, pset.queryFout, pset.logfile); @@ -835,14 +832,14 @@ SendQuery(const char *query) PGresult *results; PGTransactionStatusType transaction_status; double elapsed_msec = 0; - bool OK, - on_error_rollback_savepoint = false; + bool OK = false; + bool on_error_rollback_savepoint = false; static bool on_error_rollback_warning = false; if (!pset.db) { psql_error("You are currently not connected to a database.\n"); - return false; + goto sendquery_cleanup; } if (pset.singlestep) @@ -856,7 +853,7 @@ SendQuery(const char *query) fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != NULL) if (buf[0] == 'x') - return false; + goto sendquery_cleanup; } else if (pset.echo == PSQL_ECHO_QUERIES) { @@ -887,7 +884,7 @@ SendQuery(const char *query) psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); - return false; + goto sendquery_cleanup; } PQclear(results); transaction_status = PQtransactionStatus(pset.db); @@ -912,7 +909,7 @@ SendQuery(const char *query) psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); - return false; + goto sendquery_cleanup; } PQclear(results); on_error_rollback_savepoint = true; @@ -1008,10 +1005,11 @@ SendQuery(const char *query) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(svptres); + OK = false; PQclear(results); ResetCancelConn(); - return false; + goto sendquery_cleanup; } PQclear(svptres); } @@ -1037,6 +1035,17 @@ SendQuery(const char *query) PrintNotifications(); + /* perform cleanup that should occur after any attempted query */ + +sendquery_cleanup: + + /* reset \g's output-to-filename trigger */ + if (pset.gfname) + { + free(pset.gfname); + pset.gfname = NULL; + } + return OK; } @@ -1218,9 +1227,6 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) pset.queryFout = queryFout_copy; pset.queryFoutPipe = queryFoutPipe_copy; - - free(pset.gfname); - pset.gfname = NULL; } else if (did_pager) { |