2929MainLoop (PsqlSettings * pset ,FILE * source )
3030{
3131PQExpBuffer query_buf ;/* buffer for query being accumulated */
32+ PQExpBuffer previous_buf ;/* if there isn't anything in the new buffer
33+ yet, use this one for \e, etc. */
3234char * line ;/* current line of input */
3335int len ;/* length of the line */
3436int successResult = EXIT_SUCCESS ;
@@ -63,7 +65,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
6365
6466
6567query_buf = createPQExpBuffer ();
66- if (!query_buf )
68+ previous_buf = createPQExpBuffer ();
69+ if (!query_buf || !previous_buf )
6770{
6871perror ("createPQExpBuffer" );
6972exit (EXIT_FAILURE );
@@ -80,21 +83,21 @@ MainLoop(PsqlSettings *pset, FILE *source)
8083{
8184if (slashCmdStatus == CMD_NEWEDIT )
8285{
83-
8486/*
8587 * just returned from editing the line? then just copy to the
8688 * input buffer
8789 */
88- line = strdup (query_buf -> data );
90+ line = xstrdup (query_buf -> data );
8991resetPQExpBuffer (query_buf );
90- /* reset parsing state since we are rescanning wholequery */
92+ /* reset parsing state since we are rescanning wholeline */
9193xcomment = false;
9294in_quote = 0 ;
9395paren_level = 0 ;
96+ slashCmdStatus = CMD_UNKNOWN ;
9497}
9598else
9699{
97-
100+ fflush ( stdout );
98101/*
99102 * otherwise, set interactive prompt if necessary and get
100103 * another line
@@ -170,8 +173,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
170173puts (line );
171174
172175
173- slashCmdStatus = CMD_UNKNOWN ;
174-
175176len = strlen (line );
176177query_start = 0 ;
177178
@@ -275,11 +276,13 @@ MainLoop(PsqlSettings *pset, FILE *source)
275276/* semicolon? then send query */
276277else if (line [i ]== ';' && !was_bslash )
277278{
279+ /* delete the old query buffer from last time around */
280+ if (slashCmdStatus == CMD_SEND )
281+
278282line [i ]= '\0' ;
279283/* is there anything else on the line? */
280284if (line [query_start + strspn (line + query_start ," \t" )]!= '\0' )
281285{
282-
283286/*
284287 * insert a cosmetic newline, if this is not the first
285288 * line in the buffer
@@ -292,8 +295,11 @@ MainLoop(PsqlSettings *pset, FILE *source)
292295
293296/* execute query */
294297success = SendQuery (pset ,query_buf -> data );
298+ slashCmdStatus = success ?CMD_SEND :CMD_ERROR ;
295299
296- resetPQExpBuffer (query_buf );
300+ resetPQExpBuffer (previous_buf );
301+ appendPQExpBufferStr (previous_buf ,query_buf -> data );
302+ resetPQExpBuffer (query_buf );
297303query_start = i + thislen ;
298304}
299305
@@ -316,7 +322,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
316322/* is there anything else on the line? */
317323if (line [query_start + strspn (line + query_start ," \t" )]!= '\0' )
318324{
319-
320325/*
321326 * insert a cosmetic newline, if this is not the first
322327 * line in the buffer
@@ -327,17 +332,27 @@ MainLoop(PsqlSettings *pset, FILE *source)
327332appendPQExpBufferStr (query_buf ,line + query_start );
328333}
329334
330- /* handle backslash command */
331-
332- slashCmdStatus = HandleSlashCmds (pset ,& line [i ],query_buf ,& end_of_cmd );
335+ /* handle backslash command */
336+ slashCmdStatus = HandleSlashCmds (pset ,& line [i ],
337+ query_buf -> len > 0 ?query_buf :previous_buf ,
338+ & end_of_cmd );
333339
334340success = slashCmdStatus != CMD_ERROR ;
335341
342+ if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT )&&
343+ query_buf -> len == 0 ) {
344+ /* copy previous buffer to current for for handling */
345+ appendPQExpBufferStr (query_buf ,previous_buf -> data );
346+ }
347+
336348if (slashCmdStatus == CMD_SEND )
337349{
338350success = SendQuery (pset ,query_buf -> data );
339- resetPQExpBuffer (query_buf );
340351query_start = i + thislen ;
352+
353+ resetPQExpBuffer (previous_buf );
354+ appendPQExpBufferStr (previous_buf ,query_buf -> data );
355+ resetPQExpBuffer (query_buf );
341356}
342357
343358/* is there anything left after the backslash command? */
@@ -358,13 +373,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
358373}/* for (line) */
359374
360375
361- if (!success && die_on_error && !pset -> cur_cmd_interactive )
362- {
363- successResult = EXIT_USER ;
364- break ;
365- }
366-
367-
368376if (slashCmdStatus == CMD_TERMINATE )
369377{
370378successResult = EXIT_SUCCESS ;
@@ -387,7 +395,17 @@ MainLoop(PsqlSettings *pset, FILE *source)
387395if (query_buf -> data [0 ]!= '\0' && GetVariableBool (pset -> vars ,"singleline" ))
388396{
389397success = SendQuery (pset ,query_buf -> data );
390- resetPQExpBuffer (query_buf );
398+ slashCmdStatus = success ?CMD_SEND :CMD_ERROR ;
399+ resetPQExpBuffer (previous_buf );
400+ appendPQExpBufferStr (previous_buf ,query_buf -> data );
401+ resetPQExpBuffer (query_buf );
402+ }
403+
404+
405+ if (!success && die_on_error && !pset -> cur_cmd_interactive )
406+ {
407+ successResult = EXIT_USER ;
408+ break ;
391409}
392410
393411
@@ -397,9 +415,10 @@ MainLoop(PsqlSettings *pset, FILE *source)
397415successResult = EXIT_BADCONN ;
398416break ;
399417}
400- }/* while */
418+ }/* while !EOF */
401419
402420destroyPQExpBuffer (query_buf );
421+ destroyPQExpBuffer (previous_buf );
403422
404423pset -> cur_cmd_source = prev_cmd_source ;
405424pset -> cur_cmd_interactive = prev_cmd_interactive ;