34{
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;
46 bool line_saved_in_history;
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;
56
57 /* Save the prior command source */
61 /* pset.stmt_lineno does not need to be saved and restored */
62
63 /* Establish new source */
68
69 /* Create working state */
73
81
82 /* main loop to get queries and execute them */
84 {
85 /*
86 * Clean up after a previous Control-C
87 */
89 {
91 {
92 /*
93 * You get here if you stopped a script with Ctrl-C.
94 */
96 break;
97 }
98
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 */
108 {
109 /* got here with longjmp */
110
111 /* reset parsing state */
116 count_eof = 0;
119 need_redisplay = false;
122
124 {
126
127 /*
128 * if interactive user is in an \if block, then Ctrl-C will
129 * exit from the innermost \if.
130 */
132 {
135 }
136 }
137 else
138 {
140 break;
141 }
142 }
143
145
146 /*
147 * get another line
148 */
150 {
151 /* May need to reset prompt, eg after \r command */
152 if (query_buf->
len == 0)
154 /* If query buffer came from \e, redisplay it with a prompt */
155 if (need_redisplay)
156 {
157 if (query_buf->
len > 0)
158 {
162 }
163 need_redisplay = false;
164 }
165 /* Now we can fetch a line */
167 query_buf);
168 }
169 else
170 {
172 if (!line && ferror(
source))
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
190 {
193 continue;
194 }
195
197 }
198 break;
199 }
200
201 count_eof = 0;
202
204
205 /* ignore UTF-8 Unicode byte-order mark */
207 memmove(line, line + 3, strlen(line + 3) + 1);
208
209 /* Detect attempts to run custom-format dumps as SQL scripts */
211 strncmp(line, "PGDMP", 5) == 0)
212 {
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"));
218 break;
219 }
220
221 /* no further processing of empty lines, unless within a literal */
223 {
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 */
244 {
245 rest_of_line = first_word + 4;
246 found_help = true;
247 }
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"));
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 {
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 */
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 &&
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);
364 }
365
366 /* insert newlines into query buffer between source lines */
367 if (query_buf->
len > 0)
368 {
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. */
377
378 /*
379 * Parse line, looking for command separators.
380 */
384 line_saved_in_history = false;
385
386 while (
success || !die_on_error)
387 {
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
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')
411 }
412
415
416 /*
417 * Send command if semicolon found, or if end of line and we're in
418 * single-line mode.
419 */
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 */
430 {
433 line_saved_in_history = true;
434 }
435
436 /* execute query unless we're in an inactive \if branch */
438 {
442
443 /* transfer query to previous_buf by pointer-swapping */
444 {
446
447 previous_buf = query_buf;
448 query_buf = swap_buf;
449 }
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 */
464 /* note that query_buf doesn't change state */
465 }
466 }
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円';
484 }
485 added_nl_pos = -1;
486
487 /* save backslash command in history */
489 {
492 line_saved_in_history = true;
493 }
494
495 /* execute backslash command */
497 cond_stack,
498 query_buf,
499 previous_buf);
500
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 */
509
511 {
512 /* should not see this in inactive branch */
514
516
517 /* transfer query to previous_buf by pointer-swapping */
518 {
520
521 previous_buf = query_buf;
522 query_buf = swap_buf;
523 }
525
526 /* flush any paren nesting info after forced send */
528 }
530 {
531 /* should not see this in inactive branch */
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')
537 /* rescan query_buf as new input */
542 /* reset parsing state since we are rescanning whole line */
546 line_saved_in_history = false;
548 /* we'll want to redisplay after parsing what we have */
549 need_redisplay = true;
550 }
552 break;
553 }
554
555 /* fall out of loop if lexer reached 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)
572 if (query_buf->
len == 0)
574 }
575
578
580 {
582 break;
583 }
584
586 {
589 /* Have we lost the db connection? */
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 */
602 {
603 /* save query in history */
604 /* currently unneeded since we don't use this block if interactive */
605#ifdef NOT_USED
608#endif
609
610 /* execute query unless we're in an inactive \if branch */
612 {
614 }
615 else
616 {
618 pg_log_error(
"query ignored; use \\endif or Ctrl-C to exit current \\if block");
620 }
621
626 }
627
628 /*
629 * Check for unbalanced \if-\endifs unless user explicitly quit, or the
630 * script is erroring out
631 */
635 {
636 pg_log_error(
"reached EOF without finding closing \\endif(s)");
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 */
649
653
656
660
661 return successResult;
662} /* MainLoop() */
volatile sig_atomic_t sigint_interrupt_enabled
sigjmp_buf sigint_interrupt_jmp
bool standard_strings(void)
bool SendQuery(const char *query)
backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
enum _backslashResult backslashResult
ConditionalStack conditional_stack_create(void)
bool conditional_stack_pop(ConditionalStack cstack)
void conditional_stack_destroy(ConditionalStack cstack)
bool conditional_active(ConditionalStack cstack)
bool conditional_stack_empty(ConditionalStack cstack)
char * pg_strdup(const char *in)
volatile sig_atomic_t cancel_pressed
Assert(PointerIsAligned(start, uint64))
#define pg_log_error(...)
const PsqlScanCallbacks psqlscan_callbacks
static rewind_source * source
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
PQExpBuffer createPQExpBuffer(void)
void resetPQExpBuffer(PQExpBuffer str)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
#define PQExpBufferBroken(str)
char * get_prompt(promptStatus_t status, ConditionalStack cstack)
enum _promptStatus promptStatus_t
void psql_scan_reset(PsqlScanState state)
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)
bool psql_scan_in_quote(PsqlScanState state)
void psql_scan_finish(PsqlScanState state)