@@ -148,11 +148,11 @@ static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cst
148
148
PQExpBuffer query_buf );
149
149
static void discard_query_text (PsqlScanState scan_state , ConditionalStack cstack ,
150
150
PQExpBuffer query_buf );
151
- static void copy_previous_query (PQExpBuffer query_buf , PQExpBuffer previous_buf );
151
+ static bool copy_previous_query (PQExpBuffer query_buf , PQExpBuffer previous_buf );
152
152
static bool do_connect (enum trivalue reuse_previous_specification ,
153
153
char * dbname , char * user , char * host , char * port );
154
154
static bool do_edit (const char * filename_arg , PQExpBuffer query_buf ,
155
- int lineno , bool * edited );
155
+ int lineno , bool discard_on_quit , bool * edited );
156
156
static bool do_shell (const char * command );
157
157
static bool do_watch (PQExpBuffer query_buf , double sleep );
158
158
static bool lookup_object_oid (EditableObjectType obj_type , const char * desc ,
@@ -418,7 +418,7 @@ exec_command(const char *cmd,
418
418
* the individual command subroutines.
419
419
*/
420
420
if (status == PSQL_CMD_SEND )
421
- copy_previous_query (query_buf , previous_buf );
421
+ ( void ) copy_previous_query (query_buf , previous_buf );
422
422
423
423
return status ;
424
424
}
@@ -1004,14 +1004,27 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch,
1004
1004
}
1005
1005
if (status != PSQL_CMD_ERROR )
1006
1006
{
1007
+ bool discard_on_quit ;
1008
+
1007
1009
expand_tilde (& fname );
1008
1010
if (fname )
1011
+ {
1009
1012
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
+ }
1010
1026
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 ))
1015
1028
status = PSQL_CMD_NEWEDIT ;
1016
1029
else
1017
1030
status = PSQL_CMD_ERROR ;
@@ -1134,7 +1147,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
1134
1147
{
1135
1148
bool edited = false;
1136
1149
1137
- if (!do_edit (NULL , query_buf , lineno , & edited ))
1150
+ if (!do_edit (NULL , query_buf , lineno , true, & edited ))
1138
1151
status = PSQL_CMD_ERROR ;
1139
1152
else if (!edited )
1140
1153
puts (_ ("No changes" ));
@@ -2637,7 +2650,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
2637
2650
}
2638
2651
2639
2652
/* 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 );
2641
2654
2642
2655
success = do_watch (query_buf , sleep );
2643
2656
@@ -2961,12 +2974,19 @@ discard_query_text(PsqlScanState scan_state, ConditionalStack cstack,
2961
2974
* This is used by various slash commands for which re-execution of a
2962
2975
* previous query is a common usage. For convenience, we allow the
2963
2976
* 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".
2964
2980
*/
2965
- static void
2981
+ static bool
2966
2982
copy_previous_query (PQExpBuffer query_buf , PQExpBuffer previous_buf )
2967
2983
{
2968
2984
if (query_buf && query_buf -> len == 0 )
2985
+ {
2969
2986
appendPQExpBufferStr (query_buf , previous_buf -> data );
2987
+ return true;
2988
+ }
2989
+ return false;
2970
2990
}
2971
2991
2972
2992
/*
@@ -3647,10 +3667,11 @@ UnsyncVariables(void)
3647
3667
3648
3668
3649
3669
/*
3650
- * do_edit -- handler for \e
3670
+ * helper for do_edit(): actually invoke the editor
3651
3671
*
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.)
3654
3675
*/
3655
3676
static bool
3656
3677
editFile (const char * fname , int lineno )
@@ -3719,10 +3740,23 @@ editFile(const char *fname, int lineno)
3719
3740
}
3720
3741
3721
3742
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
+ */
3723
3757
static bool
3724
3758
do_edit (const char * filename_arg , PQExpBuffer query_buf ,
3725
- int lineno , bool * edited )
3759
+ int lineno , bool discard_on_quit , bool * edited )
3726
3760
{
3727
3761
char fnametmp [MAXPGPATH ];
3728
3762
FILE * stream = NULL ;
@@ -3870,6 +3904,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf,
3870
3904
{
3871
3905
pg_log_error ("%s: %m" , fname );
3872
3906
error = true;
3907
+ resetPQExpBuffer (query_buf );
3873
3908
}
3874
3909
else if (edited )
3875
3910
{
@@ -3879,6 +3914,15 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf,
3879
3914
fclose (stream );
3880
3915
}
3881
3916
}
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
+ }
3882
3926
3883
3927
/* remove temp file */
3884
3928
if (!filename_arg )
0 commit comments