Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit101d6ae

Browse files
committed
Prevent "\g filename" from affecting subsequent commands after an error.
In the previous coding, psql's state variable saying that output shouldgo to a file was only reset after successful completion of a queryreturning tuples. Thus for example,regression=# select 1/0regression-# \g somefileERROR: division by zeroregression=# select 1/2;regression=#... huh, I wonder where that output went. Even more oddly, the statewas not reset even if it's the file that's causing the failure:regression=# select 1/2 \g /foo/foo: Permission deniedregression=# select 1/2;/foo: Permission deniedregression=# select 1/2;/foo: Permission deniedThis seems to me not to satisfy the principle of least surprise.\g is certainly not documented in a way that suggests its effects areat all persistent.To fix, adjust the code so that the flag is reset at exit from SendQueryno matter what happened.Noted while reviewing the \gset patch, which had comparable issues.Arguably this is a bug fix, but I'll refrain from back-patching for now.
1 parent84725aa commit101d6ae

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,9 +1608,13 @@ Tue Oct 26 21:40:57 CEST 1999
16081608
optionally stores the query's output in <replaceable
16091609
class="parameter">filename</replaceable> or pipes the output
16101610
into a separate Unix shell executing <replaceable
1611-
class="parameter">command</replaceable>. A bare
1612-
<literal>\g</literal> is virtually equivalent to a semicolon. A
1613-
<literal>\g</literal> with argument is a <quote>one-shot</quote>
1611+
class="parameter">command</replaceable>. The file or command is
1612+
written to only if the query successfully returns zero or more tuples,
1613+
not if the query fails or is a non-data-returning SQL command.
1614+
</para>
1615+
<para>
1616+
A bare <literal>\g</literal> is essentially equivalent to a semicolon.
1617+
A <literal>\g</literal> with argument is a <quote>one-shot</quote>
16141618
alternative to the <command>\o</command> command.
16151619
</para>
16161620
</listitem>

‎src/bin/psql/command.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ exec_command(const char *cmd,
731731
free(fname);
732732
}
733733

734-
/* \g means send query */
734+
/* \g[filename]means send query, optionally with output to file/pipe */
735735
elseif (strcmp(cmd,"g")==0)
736736
{
737737
char*fname=psql_scan_slash_option(scan_state,

‎src/bin/psql/common.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,6 @@ PrintQueryTuples(const PGresult *results)
607607

608608
pset.queryFout=queryFout_copy;
609609
pset.queryFoutPipe=queryFoutPipe_copy;
610-
611-
free(pset.gfname);
612-
pset.gfname=NULL;
613610
}
614611
else
615612
printQuery(results,&my_popt,pset.queryFout,pset.logfile);
@@ -835,14 +832,14 @@ SendQuery(const char *query)
835832
PGresult*results;
836833
PGTransactionStatusTypetransaction_status;
837834
doubleelapsed_msec=0;
838-
boolOK,
839-
on_error_rollback_savepoint= false;
835+
boolOK= false;
836+
boolon_error_rollback_savepoint= false;
840837
staticboolon_error_rollback_warning= false;
841838

842839
if (!pset.db)
843840
{
844841
psql_error("You are currently not connected to a database.\n");
845-
return false;
842+
gotosendquery_cleanup;
846843
}
847844

848845
if (pset.singlestep)
@@ -856,7 +853,7 @@ SendQuery(const char *query)
856853
fflush(stdout);
857854
if (fgets(buf,sizeof(buf),stdin)!=NULL)
858855
if (buf[0]=='x')
859-
return false;
856+
gotosendquery_cleanup;
860857
}
861858
elseif (pset.echo==PSQL_ECHO_QUERIES)
862859
{
@@ -887,7 +884,7 @@ SendQuery(const char *query)
887884
psql_error("%s",PQerrorMessage(pset.db));
888885
PQclear(results);
889886
ResetCancelConn();
890-
return false;
887+
gotosendquery_cleanup;
891888
}
892889
PQclear(results);
893890
transaction_status=PQtransactionStatus(pset.db);
@@ -912,7 +909,7 @@ SendQuery(const char *query)
912909
psql_error("%s",PQerrorMessage(pset.db));
913910
PQclear(results);
914911
ResetCancelConn();
915-
return false;
912+
gotosendquery_cleanup;
916913
}
917914
PQclear(results);
918915
on_error_rollback_savepoint= true;
@@ -1008,10 +1005,11 @@ SendQuery(const char *query)
10081005
{
10091006
psql_error("%s",PQerrorMessage(pset.db));
10101007
PQclear(svptres);
1008+
OK= false;
10111009

10121010
PQclear(results);
10131011
ResetCancelConn();
1014-
return false;
1012+
gotosendquery_cleanup;
10151013
}
10161014
PQclear(svptres);
10171015
}
@@ -1037,6 +1035,17 @@ SendQuery(const char *query)
10371035

10381036
PrintNotifications();
10391037

1038+
/* perform cleanup that should occur after any attempted query */
1039+
1040+
sendquery_cleanup:
1041+
1042+
/* reset \g's output-to-filename trigger */
1043+
if (pset.gfname)
1044+
{
1045+
free(pset.gfname);
1046+
pset.gfname=NULL;
1047+
}
1048+
10401049
returnOK;
10411050
}
10421051

@@ -1218,9 +1227,6 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
12181227

12191228
pset.queryFout=queryFout_copy;
12201229
pset.queryFoutPipe=queryFoutPipe_copy;
1221-
1222-
free(pset.gfname);
1223-
pset.gfname=NULL;
12241230
}
12251231
elseif (did_pager)
12261232
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp