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