PostgreSQL Source Code  git master
mainloop.c
Go to the documentation of this file.
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2020, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/mainloop.c
7  */
8 #include "postgres_fe.h"
9 
10 #include "command.h"
11 #include "common.h"
12 #include "common/logging.h"
13 #include "input.h"
14 #include "mainloop.h"
15 #include "mb/pg_wchar.h"
16 #include "prompt.h"
17 #include "settings.h"
18 
19 /* callback functions for our flex lexer */
22 };
23 
24 
25 /*
26  * Main processing loop for reading lines of input
27  * and sending them to the backend.
28  *
29  * This loop is re-entrant. May be called by \i command
30  * which reads input from a file.
31  */
32 int
33 MainLoop(FILE *source)
34 {
35  PsqlScanState scan_state; /* lexer working state */
36  ConditionalStack cond_stack; /* \if status stack */
37  volatile PQExpBuffer query_buf; /* buffer for query being accumulated */
38  volatile PQExpBuffer previous_buf; /* if there isn't anything in the new
39  * buffer yet, use this one for \e,
40  * etc. */
41  PQExpBuffer history_buf; /* earlier lines of a multi-line command, not
42  * yet saved to readline history */
43  char *line; /* current line of input */
44  int added_nl_pos;
45  bool success;
46  bool line_saved_in_history;
47  volatile int successResult = EXIT_SUCCESS;
48  volatile backslashResult slashCmdStatus = PSQL_CMD_UNKNOWN;
49  volatile promptStatus_t prompt_status = PROMPT_READY;
50  volatile bool need_redisplay = false;
51  volatile int count_eof = 0;
52  volatile bool die_on_error = false;
53  FILE *prev_cmd_source;
54  bool prev_cmd_interactive;
55  uint64 prev_lineno;
56 
57  /* Save the prior command source */
58  prev_cmd_source = pset.cur_cmd_source;
59  prev_cmd_interactive = pset.cur_cmd_interactive;
60  prev_lineno = pset.lineno;
61  /* pset.stmt_lineno does not need to be saved and restored */
62 
63  /* Establish new source */
64  pset.cur_cmd_source = source;
65  pset.cur_cmd_interactive = ((source == stdin) && !pset.notty);
66  pset.lineno = 0;
67  pset.stmt_lineno = 1;
68 
69  /* Create working state */
70  scan_state = psql_scan_create(&psqlscan_callbacks);
71  cond_stack = conditional_stack_create();
72  psql_scan_set_passthrough(scan_state, (void *) cond_stack);
73 
74  query_buf = createPQExpBuffer();
75  previous_buf = createPQExpBuffer();
76  history_buf = createPQExpBuffer();
77  if (PQExpBufferBroken(query_buf) ||
78  PQExpBufferBroken(previous_buf) ||
79  PQExpBufferBroken(history_buf))
80  {
81  pg_log_error("out of memory");
82  exit(EXIT_FAILURE);
83  }
84 
85  /* main loop to get queries and execute them */
86  while (successResult == EXIT_SUCCESS)
87  {
88  /*
89  * Clean up after a previous Control-C
90  */
91  if (cancel_pressed)
92  {
94  {
95  /*
96  * You get here if you stopped a script with Ctrl-C.
97  */
98  successResult = EXIT_USER;
99  break;
100  }
101 
102  cancel_pressed = false;
103  }
104 
105  /*
106  * Establish longjmp destination for exiting from wait-for-input. We
107  * must re-do this each time through the loop for safety, since the
108  * jmpbuf might get changed during command execution.
109  */
110  if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
111  {
112  /* got here with longjmp */
113 
114  /* reset parsing state */
115  psql_scan_finish(scan_state);
116  psql_scan_reset(scan_state);
117  resetPQExpBuffer(query_buf);
118  resetPQExpBuffer(history_buf);
119  count_eof = 0;
120  slashCmdStatus = PSQL_CMD_UNKNOWN;
121  prompt_status = PROMPT_READY;
122  need_redisplay = false;
123  pset.stmt_lineno = 1;
124  cancel_pressed = false;
125 
127  {
128  putc('\n', stdout);
129 
130  /*
131  * if interactive user is in an \if block, then Ctrl-C will
132  * exit from the innermost \if.
133  */
134  if (!conditional_stack_empty(cond_stack))
135  {
136  pg_log_error("\\if: escaped");
137  conditional_stack_pop(cond_stack);
138  }
139  }
140  else
141  {
142  successResult = EXIT_USER;
143  break;
144  }
145  }
146 
147  fflush(stdout);
148 
149  /*
150  * get another line
151  */
153  {
154  /* May need to reset prompt, eg after \r command */
155  if (query_buf->len == 0)
156  prompt_status = PROMPT_READY;
157  /* If query buffer came from \e, redisplay it with a prompt */
158  if (need_redisplay)
159  {
160  if (query_buf->len > 0)
161  {
162  fputs(get_prompt(PROMPT_READY, cond_stack), stdout);
163  fputs(query_buf->data, stdout);
164  fflush(stdout);
165  }
166  need_redisplay = false;
167  }
168  /* Now we can fetch a line */
169  line = gets_interactive(get_prompt(prompt_status, cond_stack),
170  query_buf);
171  }
172  else
173  {
174  line = gets_fromFile(source);
175  if (!line && ferror(source))
176  successResult = EXIT_FAILURE;
177  }
178 
179  /*
180  * query_buf holds query already accumulated. line is the malloc'd
181  * new line of input (note it must be freed before looping around!)
182  */
183 
184  /* No more input. Time to quit, or \i done */
185  if (line == NULL)
186  {
188  {
189  /* This tries to mimic bash's IGNOREEOF feature. */
190  count_eof++;
191 
192  if (count_eof < pset.ignoreeof)
193  {
194  if (!pset.quiet)
195  printf(_("Use \"\\q\" to leave %s.\n"), pset.progname);
196  continue;
197  }
198 
199  puts(pset.quiet ? "" : "\\q");
200  }
201  break;
202  }
203 
204  count_eof = 0;
205 
206  pset.lineno++;
207 
208  /* ignore UTF-8 Unicode byte-order mark */
209  if (pset.lineno == 1 && pset.encoding == PG_UTF8 && strncmp(line, "\xef\xbb\xbf", 3) == 0)
210  memmove(line, line + 3, strlen(line + 3) + 1);
211 
212  /* Detect attempts to run custom-format dumps as SQL scripts */
213  if (pset.lineno == 1 && !pset.cur_cmd_interactive &&
214  strncmp(line, "PGDMP", 5) == 0)
215  {
216  free(line);
217  puts(_("The input is a PostgreSQL custom-format dump.\n"
218  "Use the pg_restore command-line client to restore this dump to a database.\n"));
219  fflush(stdout);
220  successResult = EXIT_FAILURE;
221  break;
222  }
223 
224  /* no further processing of empty lines, unless within a literal */
225  if (line[0] == '\0' && !psql_scan_in_quote(scan_state))
226  {
227  free(line);
228  continue;
229  }
230 
231  /* Recognize "help", "quit", "exit" only in interactive mode */
233  {
234  char *first_word = line;
235  char *rest_of_line = NULL;
236  bool found_help = false;
237  bool found_exit_or_quit = false;
238  bool found_q = false;
239 
240  /*
241  * The assistance words, help/exit/quit, must have no whitespace
242  * before them, and only whitespace after, with an optional
243  * semicolon. This prevents indented use of these words, perhaps
244  * as identifiers, from invoking the assistance behavior.
245  */
246  if (pg_strncasecmp(first_word, "help", 4) == 0)
247  {
248  rest_of_line = first_word + 4;
249  found_help = true;
250  }
251  else if (pg_strncasecmp(first_word, "exit", 4) == 0 ||
252  pg_strncasecmp(first_word, "quit", 4) == 0)
253  {
254  rest_of_line = first_word + 4;
255  found_exit_or_quit = true;
256  }
257  else if (strncmp(first_word, "\\q", 2) == 0)
258  {
259  rest_of_line = first_word + 2;
260  found_q = true;
261  }
262 
263  /*
264  * If we found a command word, check whether the rest of the line
265  * contains only whitespace plus maybe one semicolon. If not,
266  * ignore the command word after all. These commands are only for
267  * compatibility with other SQL clients and are not documented.
268  */
269  if (rest_of_line != NULL)
270  {
271  /*
272  * Ignore unless rest of line is whitespace, plus maybe one
273  * semicolon
274  */
275  while (isspace((unsigned char) *rest_of_line))
276  ++rest_of_line;
277  if (*rest_of_line == ';')
278  ++rest_of_line;
279  while (isspace((unsigned char) *rest_of_line))
280  ++rest_of_line;
281  if (*rest_of_line != '\0')
282  {
283  found_help = false;
284  found_exit_or_quit = false;
285  }
286  }
287 
288  /*
289  * "help" is only a command when the query buffer is empty, but we
290  * emit a one-line message even when it isn't to help confused
291  * users. The text is still added to the query buffer in that
292  * case.
293  */
294  if (found_help)
295  {
296  if (query_buf->len != 0)
297 #ifndef WIN32
298  puts(_("Use \\? for help or press control-C to clear the input buffer."));
299 #else
300  puts(_("Use \\? for help."));
301 #endif
302  else
303  {
304  puts(_("You are using psql, the command-line interface to PostgreSQL."));
305  printf(_("Type: \\copyright for distribution terms\n"
306  " \\h for help with SQL commands\n"
307  " \\? for help with psql commands\n"
308  " \\g or terminate with semicolon to execute query\n"
309  " \\q to quit\n"));
310  free(line);
311  fflush(stdout);
312  continue;
313  }
314  }
315 
316  /*
317  * "quit" and "exit" are only commands when the query buffer is
318  * empty, but we emit a one-line message even when it isn't to
319  * help confused users. The text is still added to the query
320  * buffer in that case.
321  */
322  if (found_exit_or_quit)
323  {
324  if (query_buf->len != 0)
325  {
326  if (prompt_status == PROMPT_READY ||
327  prompt_status == PROMPT_CONTINUE ||
328  prompt_status == PROMPT_PAREN)
329  puts(_("Use \\q to quit."));
330  else
331 #ifndef WIN32
332  puts(_("Use control-D to quit."));
333 #else
334  puts(_("Use control-C to quit."));
335 #endif
336  }
337  else
338  {
339  /* exit app */
340  free(line);
341  fflush(stdout);
342  successResult = EXIT_SUCCESS;
343  break;
344  }
345  }
346 
347  /*
348  * If they typed "\q" in a place where "\q" is not active, supply
349  * a hint. The text is still added to the query buffer.
350  */
351  if (found_q && query_buf->len != 0 &&
352  prompt_status != PROMPT_READY &&
353  prompt_status != PROMPT_CONTINUE &&
354  prompt_status != PROMPT_PAREN)
355 #ifndef WIN32
356  puts(_("Use control-D to quit."));
357 #else
358  puts(_("Use control-C to quit."));
359 #endif
360  }
361 
362  /* echo back if flag is set, unless interactive */
364  {
365  puts(line);
366  fflush(stdout);
367  }
368 
369  /* insert newlines into query buffer between source lines */
370  if (query_buf->len > 0)
371  {
372  appendPQExpBufferChar(query_buf, '\n');
373  added_nl_pos = query_buf->len;
374  }
375  else
376  added_nl_pos = -1; /* flag we didn't add one */
377 
378  /* Setting this will not have effect until next line. */
379  die_on_error = pset.on_error_stop;
380 
381  /*
382  * Parse line, looking for command separators.
383  */
384  psql_scan_setup(scan_state, line, strlen(line),
386  success = true;
387  line_saved_in_history = false;
388 
389  while (success || !die_on_error)
390  {
391  PsqlScanResult scan_result;
392  promptStatus_t prompt_tmp = prompt_status;
393  size_t pos_in_query;
394  char *tmp_line;
395 
396  pos_in_query = query_buf->len;
397  scan_result = psql_scan(scan_state, query_buf, &prompt_tmp);
398  prompt_status = prompt_tmp;
399 
400  if (PQExpBufferBroken(query_buf))
401  {
402  pg_log_error("out of memory");
403  exit(EXIT_FAILURE);
404  }
405 
406  /*
407  * Increase statement line number counter for each linebreak added
408  * to the query buffer by the last psql_scan() call. There only
409  * will be ones to add when navigating to a statement in
410  * readline's history containing newlines.
411  */
412  tmp_line = query_buf->data + pos_in_query;
413  while (*tmp_line != '\0')
414  {
415  if (*(tmp_line++) == '\n')
416  pset.stmt_lineno++;
417  }
418 
419  if (scan_result == PSCAN_EOL)
420  pset.stmt_lineno++;
421 
422  /*
423  * Send command if semicolon found, or if end of line and we're in
424  * single-line mode.
425  */
426  if (scan_result == PSCAN_SEMICOLON ||
427  (scan_result == PSCAN_EOL && pset.singleline))
428  {
429  /*
430  * Save line in history. We use history_buf to accumulate
431  * multi-line queries into a single history entry. Note that
432  * history accumulation works on input lines, so it doesn't
433  * matter whether the query will be ignored due to \if.
434  */
435  if (pset.cur_cmd_interactive && !line_saved_in_history)
436  {
437  pg_append_history(line, history_buf);
438  pg_send_history(history_buf);
439  line_saved_in_history = true;
440  }
441 
442  /* execute query unless we're in an inactive \if branch */
443  if (conditional_active(cond_stack))
444  {
445  success = SendQuery(query_buf->data);
446  slashCmdStatus = success ? PSQL_CMD_SEND : PSQL_CMD_ERROR;
447  pset.stmt_lineno = 1;
448 
449  /* transfer query to previous_buf by pointer-swapping */
450  {
451  PQExpBuffer swap_buf = previous_buf;
452 
453  previous_buf = query_buf;
454  query_buf = swap_buf;
455  }
456  resetPQExpBuffer(query_buf);
457 
458  added_nl_pos = -1;
459  /* we need not do psql_scan_reset() here */
460  }
461  else
462  {
463  /* if interactive, warn about non-executed query */
465  pg_log_error("query ignored; use \\endif or Ctrl-C to exit current \\if block");
466  /* fake an OK result for purposes of loop checks */
467  success = true;
468  slashCmdStatus = PSQL_CMD_SEND;
469  pset.stmt_lineno = 1;
470  /* note that query_buf doesn't change state */
471  }
472  }
473  else if (scan_result == PSCAN_BACKSLASH)
474  {
475  /* handle backslash command */
476 
477  /*
478  * If we added a newline to query_buf, and nothing else has
479  * been inserted in query_buf by the lexer, then strip off the
480  * newline again. This avoids any change to query_buf when a
481  * line contains only a backslash command. Also, in this
482  * situation we force out any previous lines as a separate
483  * history entry; we don't want SQL and backslash commands
484  * intermixed in history if at all possible.
485  */
486  if (query_buf->len == added_nl_pos)
487  {
488  query_buf->data[--query_buf->len] = '\0';
489  pg_send_history(history_buf);
490  }
491  added_nl_pos = -1;
492 
493  /* save backslash command in history */
494  if (pset.cur_cmd_interactive && !line_saved_in_history)
495  {
496  pg_append_history(line, history_buf);
497  pg_send_history(history_buf);
498  line_saved_in_history = true;
499  }
500 
501  /* execute backslash command */
502  slashCmdStatus = HandleSlashCmds(scan_state,
503  cond_stack,
504  query_buf,
505  previous_buf);
506 
507  success = slashCmdStatus != PSQL_CMD_ERROR;
508 
509  /*
510  * Resetting stmt_lineno after a backslash command isn't
511  * always appropriate, but it's what we've done historically
512  * and there have been few complaints.
513  */
514  pset.stmt_lineno = 1;
515 
516  if (slashCmdStatus == PSQL_CMD_SEND)
517  {
518  /* should not see this in inactive branch */
519  Assert(conditional_active(cond_stack));
520 
521  success = SendQuery(query_buf->data);
522 
523  /* transfer query to previous_buf by pointer-swapping */
524  {
525  PQExpBuffer swap_buf = previous_buf;
526 
527  previous_buf = query_buf;
528  query_buf = swap_buf;
529  }
530  resetPQExpBuffer(query_buf);
531 
532  /* flush any paren nesting info after forced send */
533  psql_scan_reset(scan_state);
534  }
535  else if (slashCmdStatus == PSQL_CMD_NEWEDIT)
536  {
537  /* should not see this in inactive branch */
538  Assert(conditional_active(cond_stack));
539  /* ensure what came back from editing ends in a newline */
540  if (query_buf->len > 0 &&
541  query_buf->data[query_buf->len - 1] != '\n')
542  appendPQExpBufferChar(query_buf, '\n');
543  /* rescan query_buf as new input */
544  psql_scan_finish(scan_state);
545  free(line);
546  line = pg_strdup(query_buf->data);
547  resetPQExpBuffer(query_buf);
548  /* reset parsing state since we are rescanning whole line */
549  psql_scan_reset(scan_state);
550  psql_scan_setup(scan_state, line, strlen(line),
552  line_saved_in_history = false;
553  prompt_status = PROMPT_READY;
554  /* we'll want to redisplay after parsing what we have */
555  need_redisplay = true;
556  }
557  else if (slashCmdStatus == PSQL_CMD_TERMINATE)
558  break;
559  }
560 
561  /* fall out of loop if lexer reached EOL */
562  if (scan_result == PSCAN_INCOMPLETE ||
563  scan_result == PSCAN_EOL)
564  break;
565  }
566 
567  /* Add line to pending history if we didn't execute anything yet */
568  if (pset.cur_cmd_interactive && !line_saved_in_history)
569  pg_append_history(line, history_buf);
570 
571  psql_scan_finish(scan_state);
572  free(line);
573 
574  if (slashCmdStatus == PSQL_CMD_TERMINATE)
575  {
576  successResult = EXIT_SUCCESS;
577  break;
578  }
579 
581  {
582  if (!success && die_on_error)
583  successResult = EXIT_USER;
584  /* Have we lost the db connection? */
585  else if (!pset.db)
586  successResult = EXIT_BADCONN;
587  }
588  } /* while !endoffile/session */
589 
590  /*
591  * If we have a non-semicolon-terminated query at the end of file, we
592  * process it unless the input source is interactive --- in that case it
593  * seems better to go ahead and quit. Also skip if this is an error exit.
594  */
595  if (query_buf->len > 0 && !pset.cur_cmd_interactive &&
596  successResult == EXIT_SUCCESS)
597  {
598  /* save query in history */
599  /* currently unneeded since we don't use this block if interactive */
600 #ifdef NOT_USED
602  pg_send_history(history_buf);
603 #endif
604 
605  /* execute query unless we're in an inactive \if branch */
606  if (conditional_active(cond_stack))
607  {
608  success = SendQuery(query_buf->data);
609  }
610  else
611  {
613  pg_log_error("query ignored; use \\endif or Ctrl-C to exit current \\if block");
614  success = true;
615  }
616 
617  if (!success && die_on_error)
618  successResult = EXIT_USER;
619  else if (pset.db == NULL)
620  successResult = EXIT_BADCONN;
621  }
622 
623  /*
624  * Check for unbalanced \if-\endifs unless user explicitly quit, or the
625  * script is erroring out
626  */
627  if (slashCmdStatus != PSQL_CMD_TERMINATE &&
628  successResult != EXIT_USER &&
629  !conditional_stack_empty(cond_stack))
630  {
631  pg_log_error("reached EOF without finding closing \\endif(s)");
632  if (die_on_error && !pset.cur_cmd_interactive)
633  successResult = EXIT_USER;
634  }
635 
636  /*
637  * Let's just make real sure the SIGINT handler won't try to use
638  * sigint_interrupt_jmp after we exit this routine. If there is an outer
639  * MainLoop instance, it will reset sigint_interrupt_jmp to point to
640  * itself at the top of its loop, before any further interactive input
641  * happens.
642  */
643  sigint_interrupt_enabled = false;
644 
645  destroyPQExpBuffer(query_buf);
646  destroyPQExpBuffer(previous_buf);
647  destroyPQExpBuffer(history_buf);
648 
649  psql_scan_destroy(scan_state);
650  conditional_stack_destroy(cond_stack);
651 
652  pset.cur_cmd_source = prev_cmd_source;
653  pset.cur_cmd_interactive = prev_cmd_interactive;
654  pset.lineno = prev_lineno;
655 
656  return successResult;
657 } /* MainLoop() */
PSQL_ECHO echo
Definition: settings.h:134
PGconn * db
Definition: settings.h:82
PsqlScanResult
Definition: psqlscan.h:30
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:128
void pg_send_history(PQExpBuffer history_buf)
Definition: input.c:136
volatile bool sigint_interrupt_enabled
Definition: common.c:245
#define EXIT_SUCCESS
Definition: settings.h:150
PsqlSettings pset
Definition: startup.c:31
bool conditional_stack_pop(ConditionalStack cstack)
Definition: conditional.c:57
#define pg_log_error(...)
Definition: logging.h:79
PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks)
char * get_prompt(promptStatus_t status, ConditionalStack cstack)
Definition: prompt.c:65
#define printf(...)
Definition: port.h:199
bool on_error_stop
Definition: settings.h:126
FILE * cur_cmd_source
Definition: settings.h:105
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:247
#define EXIT_BADCONN
Definition: settings.h:157
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
bool cur_cmd_interactive
Definition: settings.h:107
const PsqlScanCallbacks psqlscan_callbacks
Definition: mainloop.c:20
void psql_scan_reset(PsqlScanState state)
#define EXIT_USER
Definition: settings.h:159
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
bool singleline
Definition: settings.h:128
char * gets_interactive(const char *prompt, PQExpBuffer query_buf)
Definition: input.c:67
ConditionalStack conditional_stack_create(void)
Definition: conditional.c:18
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void psql_scan_destroy(PsqlScanState state)
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
bool standard_strings(void)
Definition: common.c:2173
#define free(a)
Definition: header.h:65
enum _backslashResult backslashResult
#define Assert(condition)
Definition: c.h:745
void pg_append_history(const char *s, PQExpBuffer history_buf)
Definition: input.c:114
const char * progname
Definition: settings.h:109
int MainLoop(FILE *source)
Definition: mainloop.c:33
char * gets_fromFile(FILE *source)
Definition: input.c:188
enum _promptStatus promptStatus_t
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
PsqlScanResult psql_scan(PsqlScanState state, PQExpBuffer query_buf, promptStatus_t *prompt)
void conditional_stack_destroy(ConditionalStack cstack)
Definition: conditional.c:30
char * psql_get_variable(const char *varname, PsqlScanQuoteType quote, void *passthrough)
Definition: common.c:129
void psql_scan_set_passthrough(PsqlScanState state, void *passthrough)
uint64 lineno
Definition: settings.h:111
bool conditional_stack_empty(ConditionalStack cstack)
Definition: conditional.c:118
#define EXIT_FAILURE
Definition: settings.h:154
void psql_scan_setup(PsqlScanState state, const char *line, int line_len, int encoding, bool std_strings)
bool SendQuery(const char *query)
Definition: common.c:1179
bool psql_scan_in_quote(PsqlScanState state)
void psql_scan_finish(PsqlScanState state)
backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:204
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
int encoding
Definition: settings.h:83
static bool success
Definition: initdb.c:161
#define _(x)
Definition: elog.c:88
uint64 stmt_lineno
Definition: settings.h:112