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