29
29
MainLoop (PsqlSettings * pset ,FILE * source )
30
30
{
31
31
PQExpBuffer 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. */
32
34
char * line ;/* current line of input */
33
35
int len ;/* length of the line */
34
36
int successResult = EXIT_SUCCESS ;
@@ -63,7 +65,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
63
65
64
66
65
67
query_buf = createPQExpBuffer ();
66
- if (!query_buf )
68
+ previous_buf = createPQExpBuffer ();
69
+ if (!query_buf || !previous_buf )
67
70
{
68
71
perror ("createPQExpBuffer" );
69
72
exit (EXIT_FAILURE );
@@ -80,21 +83,21 @@ MainLoop(PsqlSettings *pset, FILE *source)
80
83
{
81
84
if (slashCmdStatus == CMD_NEWEDIT )
82
85
{
83
-
84
86
/*
85
87
* just returned from editing the line? then just copy to the
86
88
* input buffer
87
89
*/
88
- line = strdup (query_buf -> data );
90
+ line = xstrdup (query_buf -> data );
89
91
resetPQExpBuffer (query_buf );
90
- /* reset parsing state since we are rescanning wholequery */
92
+ /* reset parsing state since we are rescanning wholeline */
91
93
xcomment = false;
92
94
in_quote = 0 ;
93
95
paren_level = 0 ;
96
+ slashCmdStatus = CMD_UNKNOWN ;
94
97
}
95
98
else
96
99
{
97
-
100
+ fflush ( stdout );
98
101
/*
99
102
* otherwise, set interactive prompt if necessary and get
100
103
* another line
@@ -170,8 +173,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
170
173
puts (line );
171
174
172
175
173
- slashCmdStatus = CMD_UNKNOWN ;
174
-
175
176
len = strlen (line );
176
177
query_start = 0 ;
177
178
@@ -275,11 +276,13 @@ MainLoop(PsqlSettings *pset, FILE *source)
275
276
/* semicolon? then send query */
276
277
else if (line [i ]== ';' && !was_bslash )
277
278
{
279
+ /* delete the old query buffer from last time around */
280
+ if (slashCmdStatus == CMD_SEND )
281
+
278
282
line [i ]= '\0' ;
279
283
/* is there anything else on the line? */
280
284
if (line [query_start + strspn (line + query_start ," \t" )]!= '\0' )
281
285
{
282
-
283
286
/*
284
287
* insert a cosmetic newline, if this is not the first
285
288
* line in the buffer
@@ -292,8 +295,11 @@ MainLoop(PsqlSettings *pset, FILE *source)
292
295
293
296
/* execute query */
294
297
success = SendQuery (pset ,query_buf -> data );
298
+ slashCmdStatus = success ?CMD_SEND :CMD_ERROR ;
295
299
296
- resetPQExpBuffer (query_buf );
300
+ resetPQExpBuffer (previous_buf );
301
+ appendPQExpBufferStr (previous_buf ,query_buf -> data );
302
+ resetPQExpBuffer (query_buf );
297
303
query_start = i + thislen ;
298
304
}
299
305
@@ -316,7 +322,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
316
322
/* is there anything else on the line? */
317
323
if (line [query_start + strspn (line + query_start ," \t" )]!= '\0' )
318
324
{
319
-
320
325
/*
321
326
* insert a cosmetic newline, if this is not the first
322
327
* line in the buffer
@@ -327,17 +332,27 @@ MainLoop(PsqlSettings *pset, FILE *source)
327
332
appendPQExpBufferStr (query_buf ,line + query_start );
328
333
}
329
334
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 );
333
339
334
340
success = slashCmdStatus != CMD_ERROR ;
335
341
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
+
336
348
if (slashCmdStatus == CMD_SEND )
337
349
{
338
350
success = SendQuery (pset ,query_buf -> data );
339
- resetPQExpBuffer (query_buf );
340
351
query_start = i + thislen ;
352
+
353
+ resetPQExpBuffer (previous_buf );
354
+ appendPQExpBufferStr (previous_buf ,query_buf -> data );
355
+ resetPQExpBuffer (query_buf );
341
356
}
342
357
343
358
/* is there anything left after the backslash command? */
@@ -358,13 +373,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
358
373
}/* for (line) */
359
374
360
375
361
- if (!success && die_on_error && !pset -> cur_cmd_interactive )
362
- {
363
- successResult = EXIT_USER ;
364
- break ;
365
- }
366
-
367
-
368
376
if (slashCmdStatus == CMD_TERMINATE )
369
377
{
370
378
successResult = EXIT_SUCCESS ;
@@ -387,7 +395,17 @@ MainLoop(PsqlSettings *pset, FILE *source)
387
395
if (query_buf -> data [0 ]!= '\0' && GetVariableBool (pset -> vars ,"singleline" ))
388
396
{
389
397
success = 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 ;
391
409
}
392
410
393
411
@@ -397,9 +415,10 @@ MainLoop(PsqlSettings *pset, FILE *source)
397
415
successResult = EXIT_BADCONN ;
398
416
break ;
399
417
}
400
- }/* while */
418
+ }/* while !EOF */
401
419
402
420
destroyPQExpBuffer (query_buf );
421
+ destroyPQExpBuffer (previous_buf );
403
422
404
423
pset -> cur_cmd_source = prev_cmd_source ;
405
424
pset -> cur_cmd_interactive = prev_cmd_interactive ;