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

Commit55873a0

Browse files
committed
Improve psql's behavior when the editor is exited without saving.
When editing the previous query buffer, if the editor is exitedwithout modifying the temp file then clear the query buffer,rather than re-loading (and probably re-executing) the previousquery buffer. This reduces the probability of accidentallyre-executing something you didn't intend to.Similarly, in "\e file", if the file isn't actually modifiedthen don't load it into the query buffer. And in "\ef" and"\ev", if no changes are made then clear the query bufferinstead of loading the function or view definition into it.Cases where we fail to invoke the editor at all, or it returnsa nonzero status, are treated like the no-file-modification case.Laurenz Albe, reviewed by Jacob ChampionDiscussion:https://postgr.es/m/0ba3f2a658bac6546d9934ab6ba63a805d46a49b.camel@cybertec.at
1 parent225a22b commit55873a0

File tree

2 files changed

+66
-18
lines changed

2 files changed

+66
-18
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,9 @@ testdb=>
19701970
</para>
19711971

19721972
<para>
1973-
The new contents of the query buffer are then re-parsed according to
1973+
If you edit a file or the previous query, and you quit the editor without
1974+
modifying the file, the query buffer is cleared.
1975+
Otherwise, the new contents of the query buffer are re-parsed according to
19741976
the normal rules of <application>psql</application>, treating the
19751977
whole buffer as a single line. Any complete queries are immediately
19761978
executed; that is, if the query buffer contains or ends with a
@@ -2039,7 +2041,8 @@ Tue Oct 26 21:40:57 CEST 1999
20392041
in the form of a <command>CREATE OR REPLACE FUNCTION</command> or
20402042
<command>CREATE OR REPLACE PROCEDURE</command> command.
20412043
Editing is done in the same way as for <literal>\edit</literal>.
2042-
After the editor exits, the updated command is executed immediately
2044+
If you quit the editor without saving, the statement is discarded.
2045+
If you save and exit the editor, the updated command is executed immediately
20432046
if you added a semicolon to it. Otherwise it is redisplayed;
20442047
type semicolon or <literal>\g</literal> to send it, or <literal>\r</literal>
20452048
to cancel.
@@ -2115,7 +2118,8 @@ Tue Oct 26 21:40:57 CEST 1999
21152118
This command fetches and edits the definition of the named view,
21162119
in the form of a <command>CREATE OR REPLACE VIEW</command> command.
21172120
Editing is done in the same way as for <literal>\edit</literal>.
2118-
After the editor exits, the updated command is executed immediately
2121+
If you quit the editor without saving, the statement is discarded.
2122+
If you save and exit the editor, the updated command is executed immediately
21192123
if you added a semicolon to it. Otherwise it is redisplayed;
21202124
type semicolon or <literal>\g</literal> to send it, or <literal>\r</literal>
21212125
to cancel.

‎src/bin/psql/command.c‎

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cst
148148
PQExpBufferquery_buf);
149149
staticvoiddiscard_query_text(PsqlScanStatescan_state,ConditionalStackcstack,
150150
PQExpBufferquery_buf);
151-
staticvoidcopy_previous_query(PQExpBufferquery_buf,PQExpBufferprevious_buf);
151+
staticboolcopy_previous_query(PQExpBufferquery_buf,PQExpBufferprevious_buf);
152152
staticbooldo_connect(enumtrivaluereuse_previous_specification,
153153
char*dbname,char*user,char*host,char*port);
154154
staticbooldo_edit(constchar*filename_arg,PQExpBufferquery_buf,
155-
intlineno,bool*edited);
155+
intlineno,booldiscard_on_quit,bool*edited);
156156
staticbooldo_shell(constchar*command);
157157
staticbooldo_watch(PQExpBufferquery_buf,doublesleep);
158158
staticboollookup_object_oid(EditableObjectTypeobj_type,constchar*desc,
@@ -418,7 +418,7 @@ exec_command(const char *cmd,
418418
* the individual command subroutines.
419419
*/
420420
if (status==PSQL_CMD_SEND)
421-
copy_previous_query(query_buf,previous_buf);
421+
(void)copy_previous_query(query_buf,previous_buf);
422422

423423
returnstatus;
424424
}
@@ -1004,14 +1004,27 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch,
10041004
}
10051005
if (status!=PSQL_CMD_ERROR)
10061006
{
1007+
booldiscard_on_quit;
1008+
10071009
expand_tilde(&fname);
10081010
if (fname)
1011+
{
10091012
canonicalize_path(fname);
1013+
/* Always clear buffer if the file isn't modified */
1014+
discard_on_quit= true;
1015+
}
1016+
else
1017+
{
1018+
/*
1019+
* If query_buf is empty, recall previous query for
1020+
* editing. But in that case, the query buffer should be
1021+
* emptied if editing doesn't modify the file.
1022+
*/
1023+
discard_on_quit=copy_previous_query(query_buf,
1024+
previous_buf);
1025+
}
10101026

1011-
/* If query_buf is empty, recall previous query for editing */
1012-
copy_previous_query(query_buf,previous_buf);
1013-
1014-
if (do_edit(fname,query_buf,lineno,NULL))
1027+
if (do_edit(fname,query_buf,lineno,discard_on_quit,NULL))
10151028
status=PSQL_CMD_NEWEDIT;
10161029
else
10171030
status=PSQL_CMD_ERROR;
@@ -1134,7 +1147,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
11341147
{
11351148
booledited= false;
11361149

1137-
if (!do_edit(NULL,query_buf,lineno,&edited))
1150+
if (!do_edit(NULL,query_buf,lineno,true,&edited))
11381151
status=PSQL_CMD_ERROR;
11391152
elseif (!edited)
11401153
puts(_("No changes"));
@@ -2637,7 +2650,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
26372650
}
26382651

26392652
/* If query_buf is empty, recall and execute previous query */
2640-
copy_previous_query(query_buf,previous_buf);
2653+
(void)copy_previous_query(query_buf,previous_buf);
26412654

26422655
success=do_watch(query_buf,sleep);
26432656

@@ -2961,12 +2974,19 @@ discard_query_text(PsqlScanState scan_state, ConditionalStack cstack,
29612974
* This is used by various slash commands for which re-execution of a
29622975
* previous query is a common usage. For convenience, we allow the
29632976
* case of query_buf == NULL (and do nothing).
2977+
*
2978+
* Returns "true" if the previous query was copied into the query
2979+
* buffer, else "false".
29642980
*/
2965-
staticvoid
2981+
staticbool
29662982
copy_previous_query(PQExpBufferquery_buf,PQExpBufferprevious_buf)
29672983
{
29682984
if (query_buf&&query_buf->len==0)
2985+
{
29692986
appendPQExpBufferStr(query_buf,previous_buf->data);
2987+
return true;
2988+
}
2989+
return false;
29702990
}
29712991

29722992
/*
@@ -3647,10 +3667,11 @@ UnsyncVariables(void)
36473667

36483668

36493669
/*
3650-
* do_edit -- handler for \e
3670+
*helper fordo_edit(): actually invoke the editor
36513671
*
3652-
* If you do not specify a filename, the current query buffer will be copied
3653-
* into a temporary one.
3672+
* Returns true on success, false if we failed to invoke the editor or
3673+
* it returned nonzero status. (An error message is printed for failed-
3674+
* to-invoke cases, but not if the editor returns nonzero status.)
36543675
*/
36553676
staticbool
36563677
editFile(constchar*fname,intlineno)
@@ -3719,10 +3740,23 @@ editFile(const char *fname, int lineno)
37193740
}
37203741

37213742

3722-
/* call this one */
3743+
/*
3744+
* do_edit -- handler for \e
3745+
*
3746+
* If you do not specify a filename, the current query buffer will be copied
3747+
* into a temporary file.
3748+
*
3749+
* After this function is done, the resulting file will be copied back into the
3750+
* query buffer. As an exception to this, the query buffer will be emptied
3751+
* if the file was not modified (or the editor failed) and the caller passes
3752+
* "discard_on_quit" = true.
3753+
*
3754+
* If "edited" isn't NULL, *edited will be set to true if the query buffer
3755+
* is successfully replaced.
3756+
*/
37233757
staticbool
37243758
do_edit(constchar*filename_arg,PQExpBufferquery_buf,
3725-
intlineno,bool*edited)
3759+
intlineno,booldiscard_on_quit,bool*edited)
37263760
{
37273761
charfnametmp[MAXPGPATH];
37283762
FILE*stream=NULL;
@@ -3870,6 +3904,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf,
38703904
{
38713905
pg_log_error("%s: %m",fname);
38723906
error= true;
3907+
resetPQExpBuffer(query_buf);
38733908
}
38743909
elseif (edited)
38753910
{
@@ -3879,6 +3914,15 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf,
38793914
fclose(stream);
38803915
}
38813916
}
3917+
else
3918+
{
3919+
/*
3920+
* If the file was not modified, and the caller requested it, discard
3921+
* the query buffer.
3922+
*/
3923+
if (discard_on_quit)
3924+
resetPQExpBuffer(query_buf);
3925+
}
38823926

38833927
/* remove temp file */
38843928
if (!filename_arg)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp