PostgreSQL Source Code  git master
mainloop.c File Reference
#include "postgres_fe.h"
#include "command.h"
#include "common.h"
#include "common/logging.h"
#include "input.h"
#include "mainloop.h"
#include "mb/pg_wchar.h"
#include "prompt.h"
#include "settings.h"
Include dependency graph for mainloop.c:

Go to the source code of this file.

Functions

int MainLoop (FILE *source)
 

Variables

const PsqlScanCallbacks psqlscan_callbacks
 

Function Documentation

◆ MainLoop()

int MainLoop ( FILE *  source)

Definition at line 33 of file mainloop.c.

References _, appendPQExpBufferChar(), Assert, cancel_pressed, conditional_active(), conditional_stack_create(), conditional_stack_destroy(), conditional_stack_empty(), conditional_stack_pop(), createPQExpBuffer(), _psqlSettings::cur_cmd_interactive, _psqlSettings::cur_cmd_source, PQExpBufferData::data, _psqlSettings::db, destroyPQExpBuffer(), _psqlSettings::echo, _psqlSettings::encoding, EXIT_BADCONN, EXIT_FAILURE, EXIT_SUCCESS, EXIT_USER, free, get_prompt(), gets_fromFile(), gets_interactive(), HandleSlashCmds(), _psqlSettings::ignoreeof, PQExpBufferData::len, _psqlSettings::lineno, memmove, _psqlSettings::notty, _psqlSettings::on_error_stop, pg_append_history(), pg_log_error, pg_send_history(), pg_strdup(), pg_strncasecmp(), PG_UTF8, PQExpBufferBroken, printf, _psqlSettings::progname, PROMPT_CONTINUE, PROMPT_PAREN, PROMPT_READY, PSCAN_BACKSLASH, PSCAN_EOL, PSCAN_INCOMPLETE, PSCAN_SEMICOLON, pset, PSQL_CMD_ERROR, PSQL_CMD_NEWEDIT, PSQL_CMD_SEND, PSQL_CMD_TERMINATE, PSQL_CMD_UNKNOWN, PSQL_ECHO_ALL, psql_scan(), psql_scan_create(), psql_scan_destroy(), psql_scan_finish(), psql_scan_in_quote(), psql_scan_reset(), psql_scan_set_passthrough(), psql_scan_setup(), _psqlSettings::quiet, resetPQExpBuffer(), SendQuery(), sigint_interrupt_enabled, sigint_interrupt_jmp, _psqlSettings::singleline, standard_strings(), generate_unaccent_rules::stdout, _psqlSettings::stmt_lineno, and success.

Referenced by main(), and process_file().

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  /* Search for the words we recognize; must be first word */
241  if (pg_strncasecmp(first_word, "help", 4) == 0)
242  {
243  rest_of_line = first_word + 4;
244  found_help = true;
245  }
246  else if (pg_strncasecmp(first_word, "exit", 4) == 0 ||
247  pg_strncasecmp(first_word, "quit", 4) == 0)
248  {
249  rest_of_line = first_word + 4;
250  found_exit_or_quit = true;
251  }
252 
253  else if (strncmp(first_word, "\\q", 2) == 0)
254  {
255  rest_of_line = first_word + 2;
256  found_q = true;
257  }
258 
259  /*
260  * If we found a command word, check whether the rest of the line
261  * contains only whitespace plus maybe one semicolon. If not,
262  * ignore the command word after all. These commands are only for
263  * compatibility with other SQL clients and are not documented.
264  */
265  if (rest_of_line != NULL)
266  {
267  /*
268  * Ignore unless rest of line is whitespace, plus maybe one
269  * semicolon
270  */
271  while (isspace((unsigned char) *rest_of_line))
272  ++rest_of_line;
273  if (*rest_of_line == ';')
274  ++rest_of_line;
275  while (isspace((unsigned char) *rest_of_line))
276  ++rest_of_line;
277  if (*rest_of_line != '\0')
278  {
279  found_help = false;
280  found_exit_or_quit = false;
281  }
282  }
283 
284  /*
285  * "help" is only a command when the query buffer is empty, but we
286  * emit a one-line message even when it isn't to help confused
287  * users. The text is still added to the query buffer in that
288  * case.
289  */
290  if (found_help)
291  {
292  if (query_buf->len != 0)
293 #ifndef WIN32
294  puts(_("Use \\? for help or press control-C to clear the input buffer."));
295 #else
296  puts(_("Use \\? for help."));
297 #endif
298  else
299  {
300  puts(_("You are using psql, the command-line interface to PostgreSQL."));
301  printf(_("Type: \\copyright for distribution terms\n"
302  " \\h for help with SQL commands\n"
303  " \\? for help with psql commands\n"
304  " \\g or terminate with semicolon to execute query\n"
305  " \\q to quit\n"));
306  free(line);
307  fflush(stdout);
308  continue;
309  }
310  }
311 
312  /*
313  * "quit" and "exit" are only commands when the query buffer is
314  * empty, but we emit a one-line message even when it isn't to
315  * help confused users. The text is still added to the query
316  * buffer in that case.
317  */
318  if (found_exit_or_quit)
319  {
320  if (query_buf->len != 0)
321  {
322  if (prompt_status == PROMPT_READY ||
323  prompt_status == PROMPT_CONTINUE ||
324  prompt_status == PROMPT_PAREN)
325  puts(_("Use \\q to quit."));
326  else
327 #ifndef WIN32
328  puts(_("Use control-D to quit."));
329 #else
330  puts(_("Use control-C to quit."));
331 #endif
332  }
333  else
334  {
335  /* exit app */
336  free(line);
337  fflush(stdout);
338  successResult = EXIT_SUCCESS;
339  break;
340  }
341  }
342 
343  /*
344  * If they typed "\q" in a place where "\q" is not active, supply
345  * a hint. The text is still added to the query buffer.
346  */
347  if (found_q && query_buf->len != 0 &&
348  prompt_status != PROMPT_READY &&
349  prompt_status != PROMPT_CONTINUE &&
350  prompt_status != PROMPT_PAREN)
351 #ifndef WIN32
352  puts(_("Use control-D to quit."));
353 #else
354  puts(_("Use control-C to quit."));
355 #endif
356  }
357 
358  /* echo back if flag is set, unless interactive */
360  {
361  puts(line);
362  fflush(stdout);
363  }
364 
365  /* insert newlines into query buffer between source lines */
366  if (query_buf->len > 0)
367  {
368  appendPQExpBufferChar(query_buf, '\n');
369  added_nl_pos = query_buf->len;
370  }
371  else
372  added_nl_pos = -1; /* flag we didn't add one */
373 
374  /* Setting this will not have effect until next line. */
375  die_on_error = pset.on_error_stop;
376 
377  /*
378  * Parse line, looking for command separators.
379  */
380  psql_scan_setup(scan_state, line, strlen(line),
382  success = true;
383  line_saved_in_history = false;
384 
385  while (success || !die_on_error)
386  {
387  PsqlScanResult scan_result;
388  promptStatus_t prompt_tmp = prompt_status;
389  size_t pos_in_query;
390  char *tmp_line;
391 
392  pos_in_query = query_buf->len;
393  scan_result = psql_scan(scan_state, query_buf, &prompt_tmp);
394  prompt_status = prompt_tmp;
395 
396  if (PQExpBufferBroken(query_buf))
397  {
398  pg_log_error("out of memory");
399  exit(EXIT_FAILURE);
400  }
401 
402  /*
403  * Increase statement line number counter for each linebreak added
404  * to the query buffer by the last psql_scan() call. There only
405  * will be ones to add when navigating to a statement in
406  * readline's history containing newlines.
407  */
408  tmp_line = query_buf->data + pos_in_query;
409  while (*tmp_line != '\0')
410  {
411  if (*(tmp_line++) == '\n')
412  pset.stmt_lineno++;
413  }
414 
415  if (scan_result == PSCAN_EOL)
416  pset.stmt_lineno++;
417 
418  /*
419  * Send command if semicolon found, or if end of line and we're in
420  * single-line mode.
421  */
422  if (scan_result == PSCAN_SEMICOLON ||
423  (scan_result == PSCAN_EOL && pset.singleline))
424  {
425  /*
426  * Save line in history. We use history_buf to accumulate
427  * multi-line queries into a single history entry. Note that
428  * history accumulation works on input lines, so it doesn't
429  * matter whether the query will be ignored due to \if.
430  */
431  if (pset.cur_cmd_interactive && !line_saved_in_history)
432  {
433  pg_append_history(line, history_buf);
434  pg_send_history(history_buf);
435  line_saved_in_history = true;
436  }
437 
438  /* execute query unless we're in an inactive \if branch */
439  if (conditional_active(cond_stack))
440  {
441  success = SendQuery(query_buf->data);
442  slashCmdStatus = success ? PSQL_CMD_SEND : PSQL_CMD_ERROR;
443  pset.stmt_lineno = 1;
444 
445  /* transfer query to previous_buf by pointer-swapping */
446  {
447  PQExpBuffer swap_buf = previous_buf;
448 
449  previous_buf = query_buf;
450  query_buf = swap_buf;
451  }
452  resetPQExpBuffer(query_buf);
453 
454  added_nl_pos = -1;
455  /* we need not do psql_scan_reset() here */
456  }
457  else
458  {
459  /* if interactive, warn about non-executed query */
461  pg_log_error("query ignored; use \\endif or Ctrl-C to exit current \\if block");
462  /* fake an OK result for purposes of loop checks */
463  success = true;
464  slashCmdStatus = PSQL_CMD_SEND;
465  pset.stmt_lineno = 1;
466  /* note that query_buf doesn't change state */
467  }
468  }
469  else if (scan_result == PSCAN_BACKSLASH)
470  {
471  /* handle backslash command */
472 
473  /*
474  * If we added a newline to query_buf, and nothing else has
475  * been inserted in query_buf by the lexer, then strip off the
476  * newline again. This avoids any change to query_buf when a
477  * line contains only a backslash command. Also, in this
478  * situation we force out any previous lines as a separate
479  * history entry; we don't want SQL and backslash commands
480  * intermixed in history if at all possible.
481  */
482  if (query_buf->len == added_nl_pos)
483  {
484  query_buf->data[--query_buf->len] = '\0';
485  pg_send_history(history_buf);
486  }
487  added_nl_pos = -1;
488 
489  /* save backslash command in history */
490  if (pset.cur_cmd_interactive && !line_saved_in_history)
491  {
492  pg_append_history(line, history_buf);
493  pg_send_history(history_buf);
494  line_saved_in_history = true;
495  }
496 
497  /* execute backslash command */
498  slashCmdStatus = HandleSlashCmds(scan_state,
499  cond_stack,
500  query_buf,
501  previous_buf);
502 
503  success = slashCmdStatus != PSQL_CMD_ERROR;
504 
505  /*
506  * Resetting stmt_lineno after a backslash command isn't
507  * always appropriate, but it's what we've done historically
508  * and there have been few complaints.
509  */
510  pset.stmt_lineno = 1;
511 
512  if (slashCmdStatus == PSQL_CMD_SEND)
513  {
514  /* should not see this in inactive branch */
515  Assert(conditional_active(cond_stack));
516 
517  success = SendQuery(query_buf->data);
518 
519  /* transfer query to previous_buf by pointer-swapping */
520  {
521  PQExpBuffer swap_buf = previous_buf;
522 
523  previous_buf = query_buf;
524  query_buf = swap_buf;
525  }
526  resetPQExpBuffer(query_buf);
527 
528  /* flush any paren nesting info after forced send */
529  psql_scan_reset(scan_state);
530  }
531  else if (slashCmdStatus == PSQL_CMD_NEWEDIT)
532  {
533  /* should not see this in inactive branch */
534  Assert(conditional_active(cond_stack));
535  /* ensure what came back from editing ends in a newline */
536  if (query_buf->len > 0 &&
537  query_buf->data[query_buf->len - 1] != '\n')
538  appendPQExpBufferChar(query_buf, '\n');
539  /* rescan query_buf as new input */
540  psql_scan_finish(scan_state);
541  free(line);
542  line = pg_strdup(query_buf->data);
543  resetPQExpBuffer(query_buf);
544  /* reset parsing state since we are rescanning whole line */
545  psql_scan_reset(scan_state);
546  psql_scan_setup(scan_state, line, strlen(line),
548  line_saved_in_history = false;
549  prompt_status = PROMPT_READY;
550  /* we'll want to redisplay after parsing what we have */
551  need_redisplay = true;
552  }
553  else if (slashCmdStatus == PSQL_CMD_TERMINATE)
554  break;
555  }
556 
557  /* fall out of loop if lexer reached EOL */
558  if (scan_result == PSCAN_INCOMPLETE ||
559  scan_result == PSCAN_EOL)
560  break;
561  }
562 
563  /* Add line to pending history if we didn't execute anything yet */
564  if (pset.cur_cmd_interactive && !line_saved_in_history)
565  pg_append_history(line, history_buf);
566 
567  psql_scan_finish(scan_state);
568  free(line);
569 
570  if (slashCmdStatus == PSQL_CMD_TERMINATE)
571  {
572  successResult = EXIT_SUCCESS;
573  break;
574  }
575 
577  {
578  if (!success && die_on_error)
579  successResult = EXIT_USER;
580  /* Have we lost the db connection? */
581  else if (!pset.db)
582  successResult = EXIT_BADCONN;
583  }
584  } /* while !endoffile/session */
585 
586  /*
587  * If we have a non-semicolon-terminated query at the end of file, we
588  * process it unless the input source is interactive --- in that case it
589  * seems better to go ahead and quit. Also skip if this is an error exit.
590  */
591  if (query_buf->len > 0 && !pset.cur_cmd_interactive &&
592  successResult == EXIT_SUCCESS)
593  {
594  /* save query in history */
595  /* currently unneeded since we don't use this block if interactive */
596 #ifdef NOT_USED
598  pg_send_history(history_buf);
599 #endif
600 
601  /* execute query unless we're in an inactive \if branch */
602  if (conditional_active(cond_stack))
603  {
604  success = SendQuery(query_buf->data);
605  }
606  else
607  {
609  pg_log_error("query ignored; use \\endif or Ctrl-C to exit current \\if block");
610  success = true;
611  }
612 
613  if (!success && die_on_error)
614  successResult = EXIT_USER;
615  else if (pset.db == NULL)
616  successResult = EXIT_BADCONN;
617  }
618 
619  /*
620  * Check for unbalanced \if-\endifs unless user explicitly quit, or the
621  * script is erroring out
622  */
623  if (slashCmdStatus != PSQL_CMD_TERMINATE &&
624  successResult != EXIT_USER &&
625  !conditional_stack_empty(cond_stack))
626  {
627  pg_log_error("reached EOF without finding closing \\endif(s)");
628  if (die_on_error && !pset.cur_cmd_interactive)
629  successResult = EXIT_USER;
630  }
631 
632  /*
633  * Let's just make real sure the SIGINT handler won't try to use
634  * sigint_interrupt_jmp after we exit this routine. If there is an outer
635  * MainLoop instance, it will reset sigint_interrupt_jmp to point to
636  * itself at the top of its loop, before any further interactive input
637  * happens.
638  */
639  sigint_interrupt_enabled = false;
640 
641  destroyPQExpBuffer(query_buf);
642  destroyPQExpBuffer(previous_buf);
643  destroyPQExpBuffer(history_buf);
644 
645  psql_scan_destroy(scan_state);
646  conditional_stack_destroy(cond_stack);
647 
648  pset.cur_cmd_source = prev_cmd_source;
649  pset.cur_cmd_interactive = prev_cmd_interactive;
650  pset.lineno = prev_lineno;
651 
652  return successResult;
653 } /* MainLoop() */
PSQL_ECHO echo
Definition: settings.h:133
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:149
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:70
#define printf(...)
Definition: port.h:198
bool on_error_stop
Definition: settings.h:125
FILE * cur_cmd_source
Definition: settings.h:104
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:247
#define EXIT_BADCONN
Definition: settings.h:156
volatile bool cancel_pressed
Definition: print.c:44
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:106
#define memmove(d, s, c)
Definition: c.h:1267
const PsqlScanCallbacks psqlscan_callbacks
Definition: mainloop.c:20
void psql_scan_reset(PsqlScanState state)
#define EXIT_USER
Definition: settings.h:158
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: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)
bool standard_strings(void)
Definition: common.c:2175
#define free(a)
Definition: header.h:65
enum _backslashResult backslashResult
#define Assert(condition)
Definition: c.h:739
void pg_append_history(const char *s, PQExpBuffer history_buf)
Definition: input.c:114
const char * progname
Definition: settings.h:108
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
void psql_scan_set_passthrough(PsqlScanState state, void *passthrough)
uint64 lineno
Definition: settings.h:110
bool conditional_stack_empty(ConditionalStack cstack)
Definition: conditional.c:118
#define EXIT_FAILURE
Definition: settings.h:153
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:1181
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:200
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
int encoding
Definition: settings.h:83
static bool success
Definition: initdb.c:163
#define _(x)
Definition: elog.c:87
uint64 stmt_lineno
Definition: settings.h:111

Variable Documentation

◆ psqlscan_callbacks

const PsqlScanCallbacks psqlscan_callbacks
Initial value:
= {
}
char * psql_get_variable(const char *varname, PsqlScanQuoteType quote, void *passthrough)
Definition: common.c:129

Definition at line 20 of file mainloop.c.

Referenced by main().