PostgreSQL Source Code git master
command.c
Go to the documentation of this file.
1/*
2 * psql - the PostgreSQL interactive terminal
3 *
4 * Copyright (c) 2000-2025, PostgreSQL Global Development Group
5 *
6 * src/bin/psql/command.c
7 */
8#include "postgres_fe.h"
9
10#include <ctype.h>
11#include <time.h>
12#include <pwd.h>
13#include <utime.h>
14#ifndef WIN32
15#include <sys/stat.h> /* for stat() */
16#include <sys/time.h> /* for setitimer() */
17#include <fcntl.h> /* open() flags */
18#include <unistd.h> /* for geteuid(), getpid(), stat() */
19#else
20#include <win32.h>
21#include <io.h>
22#include <fcntl.h>
23#include <direct.h>
24#include <sys/stat.h> /* for stat() */
25#endif
26
27#include "catalog/pg_class_d.h"
28#include "command.h"
29#include "common.h"
30#include "common/logging.h"
31#include "common/string.h"
32#include "copy.h"
33#include "describe.h"
34#include "fe_utils/cancel.h"
35#include "fe_utils/print.h"
37#include "help.h"
38#include "input.h"
39#include "large_obj.h"
40#include "libpq/pqcomm.h"
41#include "mainloop.h"
42#include "pqexpbuffer.h"
43#include "psqlscanslash.h"
44#include "settings.h"
45#include "variables.h"
46
47/*
48 * Editable database object types.
49 */
51{
55
56/* local function declarations */
57static backslashResult exec_command(const char *cmd,
58 PsqlScanState scan_state,
59 ConditionalStack cstack,
60 PQExpBuffer query_buf,
61 PQExpBuffer previous_buf);
62static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch);
63static backslashResult exec_command_bind(PsqlScanState scan_state, bool active_branch);
64static backslashResult exec_command_bind_named(PsqlScanState scan_state, bool active_branch,
65 const char *cmd);
66static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch);
67static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch);
68static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch,
69 const char *cmd);
71 bool active_branch, const char *cmd);
72static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch);
73static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch);
74static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch);
75static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch);
76static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch,
77 const char *cmd);
78static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
79 const char *pattern,
80 bool show_verbose, bool show_system);
81static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
82 PQExpBuffer query_buf, PQExpBuffer previous_buf);
83static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
84 PQExpBuffer query_buf, bool is_func);
85static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch,
86 const char *cmd);
88 PQExpBuffer query_buf);
90 PQExpBuffer query_buf);
92 PQExpBuffer query_buf);
93static backslashResult exec_command_endpipeline(PsqlScanState scan_state, bool active_branch);
94static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch);
95static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch);
96static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch);
97static backslashResult exec_command_flush(PsqlScanState scan_state, bool active_branch);
98static backslashResult exec_command_flushrequest(PsqlScanState scan_state, bool active_branch);
99static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch,
100 const char *cmd);
101static backslashResult process_command_g_options(char *first_option,
102 PsqlScanState scan_state,
103 bool active_branch,
104 const char *cmd);
105static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch);
106static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch,
107 const char *cmd);
108static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch);
109static backslashResult exec_command_getresults(PsqlScanState scan_state, bool active_branch);
110static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch);
111static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch);
112static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch);
113static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch,
114 const char *cmd);
116 PQExpBuffer query_buf);
117static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch,
118 const char *cmd);
119static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch,
120 const char *cmd);
121static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch);
122static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch,
123 PQExpBuffer query_buf, PQExpBuffer previous_buf);
124static backslashResult exec_command_parse(PsqlScanState scan_state, bool active_branch,
125 const char *cmd);
126static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch);
127static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch,
128 const char *cmd);
129static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch);
130static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch);
131static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch,
132 PQExpBuffer query_buf);
133static backslashResult exec_command_restrict(PsqlScanState scan_state, bool active_branch,
134 const char *cmd);
135static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch);
136static backslashResult exec_command_sendpipeline(PsqlScanState scan_state, bool active_branch);
137static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch);
138static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch,
139 const char *cmd);
140static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
141 const char *cmd, bool is_func);
142static backslashResult exec_command_startpipeline(PsqlScanState scan_state, bool active_branch);
143static backslashResult exec_command_syncpipeline(PsqlScanState scan_state, bool active_branch);
144static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch);
145static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch);
146static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch);
147static backslashResult exec_command_unrestrict(PsqlScanState scan_state, bool active_branch,
148 const char *cmd);
149static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch,
150 const char *cmd);
151static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch,
152 const char *cmd,
153 PQExpBuffer query_buf, PQExpBuffer previous_buf);
154static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch,
155 PQExpBuffer query_buf, PQExpBuffer previous_buf);
156static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch);
157static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch,
158 const char *cmd);
159static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch);
160static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch);
161static char *read_connect_arg(PsqlScanState scan_state);
163static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name);
164static void ignore_boolean_expression(PsqlScanState scan_state);
165static void ignore_slash_options(PsqlScanState scan_state);
166static void ignore_slash_filepipe(PsqlScanState scan_state);
167static void ignore_slash_whole_line(PsqlScanState scan_state);
168static bool is_branching_command(const char *cmd);
169static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack,
170 PQExpBuffer query_buf);
171static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack,
172 PQExpBuffer query_buf);
173static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf);
174static bool do_connect(enum trivalue reuse_previous_specification,
175 char *dbname, char *user, char *host, char *port);
176static void wait_until_connected(PGconn *conn);
177static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
178 int lineno, bool discard_on_quit, bool *edited);
179static bool do_shell(const char *command);
180static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows);
181static bool lookup_object_oid(EditableObjectType obj_type, const char *desc,
182 Oid *obj_oid);
183static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
185static int strip_lineno_from_objdesc(char *obj);
187static void print_with_linenumbers(FILE *output, char *lines, bool is_func);
188static void minimal_error_message(PGresult *res);
189
190static void printSSLInfo(void);
191static void printGSSInfo(void);
192static bool printPsetInfo(const char *param, printQueryOpt *popt);
193static char *pset_value_string(const char *param, printQueryOpt *popt);
194
195#ifdef WIN32
196static void checkWin32Codepage(void);
197#endif
198
199static bool restricted;
200static char *restrict_key;
201
202
203/*----------
204 * HandleSlashCmds:
205 *
206 * Handles all the different commands that start with '\'.
207 * Ordinarily called by MainLoop().
208 *
209 * scan_state is a lexer working state that is set to continue scanning
210 * just after the '\'. The lexer is advanced past the command and all
211 * arguments on return.
212 *
213 * cstack is the current \if stack state. This will be examined, and
214 * possibly modified by conditional commands.
215 *
216 * query_buf contains the query-so-far, which may be modified by
217 * execution of the backslash command (for example, \r clears it).
218 *
219 * previous_buf contains the query most recently sent to the server
220 * (empty if none yet). This should not be modified here, but some
221 * commands copy its content into query_buf.
222 *
223 * query_buf and previous_buf will be NULL when executing a "-c"
224 * command-line option.
225 *
226 * Returns a status code indicating what action is desired, see command.h.
227 *----------
228 */
229
232 ConditionalStack cstack,
233 PQExpBuffer query_buf,
234 PQExpBuffer previous_buf)
235{
236 backslashResult status;
237 char *cmd;
238 char *arg;
239
240 Assert(scan_state != NULL);
241 Assert(cstack != NULL);
242
243 /* Parse off the command name */
244 cmd = psql_scan_slash_command(scan_state);
245
246 /*
247 * And try to execute it.
248 *
249 * If we are in "restricted" mode, the only allowable backslash command is
250 * \unrestrict (to exit restricted mode).
251 */
252 if (restricted && strcmp(cmd, "unrestrict") != 0)
253 {
254 pg_log_error("backslash commands are restricted; only \\unrestrict is allowed");
255 status = PSQL_CMD_ERROR;
256 }
257 else
258 status = exec_command(cmd, scan_state, cstack, query_buf, previous_buf);
259
260 if (status == PSQL_CMD_UNKNOWN)
261 {
262 pg_log_error("invalid command \\%s", cmd);
264 pg_log_error_hint("Try \\? for help.");
265 status = PSQL_CMD_ERROR;
266 }
267
268 if (status != PSQL_CMD_ERROR)
269 {
270 /*
271 * Eat any remaining arguments after a valid command. We want to
272 * suppress evaluation of backticks in this situation, so transiently
273 * push an inactive conditional-stack entry.
274 */
275 bool active_branch = conditional_active(cstack);
276
278 while ((arg = psql_scan_slash_option(scan_state,
279 OT_NORMAL, NULL, false)))
280 {
281 if (active_branch)
282 pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd, arg);
283 free(arg);
284 }
285 conditional_stack_pop(cstack);
286 }
287 else
288 {
289 /* silently throw away rest of line after an erroneous command */
290 while ((arg = psql_scan_slash_option(scan_state,
291 OT_WHOLE_LINE, NULL, false)))
292 free(arg);
293 }
294
295 /* if there is a trailing \\, swallow it */
296 psql_scan_slash_command_end(scan_state);
297
298 free(cmd);
299
300 /* some commands write to queryFout, so make sure output is sent */
301 fflush(pset.queryFout);
302
303 return status;
304}
305
306
307/*
308 * Subroutine to actually try to execute a backslash command.
309 *
310 * The typical "success" result code is PSQL_CMD_SKIP_LINE, although some
311 * commands return something else. Failure result code is PSQL_CMD_ERROR,
312 * unless PSQL_CMD_UNKNOWN is more appropriate.
313 */
314static backslashResult
315exec_command(const char *cmd,
316 PsqlScanState scan_state,
317 ConditionalStack cstack,
318 PQExpBuffer query_buf,
319 PQExpBuffer previous_buf)
320{
321 backslashResult status;
322 bool active_branch = conditional_active(cstack);
323
324 /*
325 * In interactive mode, warn when we're ignoring a command within a false
326 * \if-branch. But we continue on, so as to parse and discard the right
327 * amount of parameter text. Each individual backslash command subroutine
328 * is responsible for doing nothing after discarding appropriate
329 * arguments, if !active_branch.
330 */
331 if (pset.cur_cmd_interactive && !active_branch &&
333 {
334 pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
335 cmd);
336 }
337
338 if (strcmp(cmd, "a") == 0)
339 status = exec_command_a(scan_state, active_branch);
340 else if (strcmp(cmd, "bind") == 0)
341 status = exec_command_bind(scan_state, active_branch);
342 else if (strcmp(cmd, "bind_named") == 0)
343 status = exec_command_bind_named(scan_state, active_branch, cmd);
344 else if (strcmp(cmd, "C") == 0)
345 status = exec_command_C(scan_state, active_branch);
346 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
347 status = exec_command_connect(scan_state, active_branch);
348 else if (strcmp(cmd, "cd") == 0)
349 status = exec_command_cd(scan_state, active_branch, cmd);
350 else if (strcmp(cmd, "close_prepared") == 0)
351 status = exec_command_close_prepared(scan_state, active_branch, cmd);
352 else if (strcmp(cmd, "conninfo") == 0)
353 status = exec_command_conninfo(scan_state, active_branch);
354 else if (pg_strcasecmp(cmd, "copy") == 0)
355 status = exec_command_copy(scan_state, active_branch);
356 else if (strcmp(cmd, "copyright") == 0)
357 status = exec_command_copyright(scan_state, active_branch);
358 else if (strcmp(cmd, "crosstabview") == 0)
359 status = exec_command_crosstabview(scan_state, active_branch);
360 else if (cmd[0] == 'd')
361 status = exec_command_d(scan_state, active_branch, cmd);
362 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
363 status = exec_command_edit(scan_state, active_branch,
364 query_buf, previous_buf);
365 else if (strcmp(cmd, "ef") == 0)
366 status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
367 else if (strcmp(cmd, "ev") == 0)
368 status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
369 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
370 strcmp(cmd, "warn") == 0)
371 status = exec_command_echo(scan_state, active_branch, cmd);
372 else if (strcmp(cmd, "elif") == 0)
373 status = exec_command_elif(scan_state, cstack, query_buf);
374 else if (strcmp(cmd, "else") == 0)
375 status = exec_command_else(scan_state, cstack, query_buf);
376 else if (strcmp(cmd, "endif") == 0)
377 status = exec_command_endif(scan_state, cstack, query_buf);
378 else if (strcmp(cmd, "endpipeline") == 0)
379 status = exec_command_endpipeline(scan_state, active_branch);
380 else if (strcmp(cmd, "encoding") == 0)
381 status = exec_command_encoding(scan_state, active_branch);
382 else if (strcmp(cmd, "errverbose") == 0)
383 status = exec_command_errverbose(scan_state, active_branch);
384 else if (strcmp(cmd, "f") == 0)
385 status = exec_command_f(scan_state, active_branch);
386 else if (strcmp(cmd, "flush") == 0)
387 status = exec_command_flush(scan_state, active_branch);
388 else if (strcmp(cmd, "flushrequest") == 0)
389 status = exec_command_flushrequest(scan_state, active_branch);
390 else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
391 status = exec_command_g(scan_state, active_branch, cmd);
392 else if (strcmp(cmd, "gdesc") == 0)
393 status = exec_command_gdesc(scan_state, active_branch);
394 else if (strcmp(cmd, "getenv") == 0)
395 status = exec_command_getenv(scan_state, active_branch, cmd);
396 else if (strcmp(cmd, "getresults") == 0)
397 status = exec_command_getresults(scan_state, active_branch);
398 else if (strcmp(cmd, "gexec") == 0)
399 status = exec_command_gexec(scan_state, active_branch);
400 else if (strcmp(cmd, "gset") == 0)
401 status = exec_command_gset(scan_state, active_branch);
402 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
403 status = exec_command_help(scan_state, active_branch);
404 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
405 status = exec_command_html(scan_state, active_branch);
406 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ||
407 strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
408 status = exec_command_include(scan_state, active_branch, cmd);
409 else if (strcmp(cmd, "if") == 0)
410 status = exec_command_if(scan_state, cstack, query_buf);
411 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
412 strcmp(cmd, "lx") == 0 || strcmp(cmd, "listx") == 0 ||
413 strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0 ||
414 strcmp(cmd, "lx+") == 0 || strcmp(cmd, "listx+") == 0 ||
415 strcmp(cmd, "l+x") == 0 || strcmp(cmd, "list+x") == 0)
416 status = exec_command_list(scan_state, active_branch, cmd);
417 else if (strncmp(cmd, "lo_", 3) == 0)
418 status = exec_command_lo(scan_state, active_branch, cmd);
419 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
420 status = exec_command_out(scan_state, active_branch);
421 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
422 status = exec_command_print(scan_state, active_branch,
423 query_buf, previous_buf);
424 else if (strcmp(cmd, "parse") == 0)
425 status = exec_command_parse(scan_state, active_branch, cmd);
426 else if (strcmp(cmd, "password") == 0)
427 status = exec_command_password(scan_state, active_branch);
428 else if (strcmp(cmd, "prompt") == 0)
429 status = exec_command_prompt(scan_state, active_branch, cmd);
430 else if (strcmp(cmd, "pset") == 0)
431 status = exec_command_pset(scan_state, active_branch);
432 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
433 status = exec_command_quit(scan_state, active_branch);
434 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
435 status = exec_command_reset(scan_state, active_branch, query_buf);
436 else if (strcmp(cmd, "restrict") == 0)
437 status = exec_command_restrict(scan_state, active_branch, cmd);
438 else if (strcmp(cmd, "s") == 0)
439 status = exec_command_s(scan_state, active_branch);
440 else if (strcmp(cmd, "sendpipeline") == 0)
441 status = exec_command_sendpipeline(scan_state, active_branch);
442 else if (strcmp(cmd, "set") == 0)
443 status = exec_command_set(scan_state, active_branch);
444 else if (strcmp(cmd, "setenv") == 0)
445 status = exec_command_setenv(scan_state, active_branch, cmd);
446 else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
447 status = exec_command_sf_sv(scan_state, active_branch, cmd, true);
448 else if (strcmp(cmd, "sv") == 0 || strcmp(cmd, "sv+") == 0)
449 status = exec_command_sf_sv(scan_state, active_branch, cmd, false);
450 else if (strcmp(cmd, "startpipeline") == 0)
451 status = exec_command_startpipeline(scan_state, active_branch);
452 else if (strcmp(cmd, "syncpipeline") == 0)
453 status = exec_command_syncpipeline(scan_state, active_branch);
454 else if (strcmp(cmd, "t") == 0)
455 status = exec_command_t(scan_state, active_branch);
456 else if (strcmp(cmd, "T") == 0)
457 status = exec_command_T(scan_state, active_branch);
458 else if (strcmp(cmd, "timing") == 0)
459 status = exec_command_timing(scan_state, active_branch);
460 else if (strcmp(cmd, "unrestrict") == 0)
461 status = exec_command_unrestrict(scan_state, active_branch, cmd);
462 else if (strcmp(cmd, "unset") == 0)
463 status = exec_command_unset(scan_state, active_branch, cmd);
464 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
465 status = exec_command_write(scan_state, active_branch, cmd,
466 query_buf, previous_buf);
467 else if (strcmp(cmd, "watch") == 0)
468 status = exec_command_watch(scan_state, active_branch,
469 query_buf, previous_buf);
470 else if (strcmp(cmd, "x") == 0)
471 status = exec_command_x(scan_state, active_branch);
472 else if (strcmp(cmd, "z") == 0 ||
473 strcmp(cmd, "zS") == 0 || strcmp(cmd, "zx") == 0 ||
474 strcmp(cmd, "zSx") == 0 || strcmp(cmd, "zxS") == 0)
475 status = exec_command_z(scan_state, active_branch, cmd);
476 else if (strcmp(cmd, "!") == 0)
477 status = exec_command_shell_escape(scan_state, active_branch);
478 else if (strcmp(cmd, "?") == 0)
479 status = exec_command_slash_command_help(scan_state, active_branch);
480 else
481 status = PSQL_CMD_UNKNOWN;
482
483 /*
484 * All the commands that return PSQL_CMD_SEND want to execute previous_buf
485 * if query_buf is empty. For convenience we implement that here, not in
486 * the individual command subroutines.
487 */
488 if (status == PSQL_CMD_SEND)
489 (void) copy_previous_query(query_buf, previous_buf);
490
491 return status;
492}
493
494
495/*
496 * \a -- toggle field alignment
497 *
498 * This makes little sense but we keep it around.
499 */
500static backslashResult
501exec_command_a(PsqlScanState scan_state, bool active_branch)
502{
503 bool success = true;
504
505 if (active_branch)
506 {
508 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
509 else
510 success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
511 }
512
514}
515
516/*
517 * \bind -- set query parameters
518 */
519static backslashResult
520exec_command_bind(PsqlScanState scan_state, bool active_branch)
521{
523
524 if (active_branch)
525 {
526 char *opt;
527 int nparams = 0;
528 int nalloc = 0;
529
531
532 while ((opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false)))
533 {
534 nparams++;
535 if (nparams > nalloc)
536 {
537 nalloc = nalloc ? nalloc * 2 : 1;
539 }
540 pset.bind_params[nparams - 1] = opt;
541 }
542
543 pset.bind_nparams = nparams;
545 }
546 else
547 ignore_slash_options(scan_state);
548
549 return status;
550}
551
552/*
553 * \bind_named -- set query parameters for an existing prepared statement
554 */
555static backslashResult
556exec_command_bind_named(PsqlScanState scan_state, bool active_branch,
557 const char *cmd)
558{
560
561 if (active_branch)
562 {
563 char *opt;
564 int nparams = 0;
565 int nalloc = 0;
566
568
569 /* get the mandatory prepared statement name */
570 opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
571 if (!opt)
572 {
573 pg_log_error("\\%s: missing required argument", cmd);
574 status = PSQL_CMD_ERROR;
575 }
576 else
577 {
578 pset.stmtName = opt;
580
581 /* set of parameters */
582 while ((opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false)))
583 {
584 nparams++;
585 if (nparams > nalloc)
586 {
587 nalloc = nalloc ? nalloc * 2 : 1;
589 }
590 pset.bind_params[nparams - 1] = opt;
591 }
592 pset.bind_nparams = nparams;
593 }
594 }
595 else
596 ignore_slash_options(scan_state);
597
598 return status;
599}
600
601/*
602 * \C -- override table title (formerly change HTML caption)
603 */
604static backslashResult
605exec_command_C(PsqlScanState scan_state, bool active_branch)
606{
607 bool success = true;
608
609 if (active_branch)
610 {
611 char *opt = psql_scan_slash_option(scan_state,
612 OT_NORMAL, NULL, true);
613
614 success = do_pset("title", opt, &pset.popt, pset.quiet);
615 free(opt);
616 }
617 else
618 ignore_slash_options(scan_state);
619
621}
622
623/*
624 * \c or \connect -- connect to database using the specified parameters.
625 *
626 * \c [-reuse-previous=BOOL] dbname user host port
627 *
628 * Specifying a parameter as '-' is equivalent to omitting it. Examples:
629 *
630 * \c - - hst Connect to current database on current port of
631 * host "hst" as current user.
632 * \c - usr - prt Connect to current database on port "prt" of current host
633 * as user "usr".
634 * \c dbs Connect to database "dbs" on current port of current host
635 * as current user.
636 */
637static backslashResult
638exec_command_connect(PsqlScanState scan_state, bool active_branch)
639{
640 bool success = true;
641
642 if (active_branch)
643 {
644 static const char prefix[] = "-reuse-previous=";
645 char *opt1,
646 *opt2,
647 *opt3,
648 *opt4;
649 enum trivalue reuse_previous = TRI_DEFAULT;
650
651 opt1 = read_connect_arg(scan_state);
652 if (opt1 != NULL && strncmp(opt1, prefix, sizeof(prefix) - 1) == 0)
653 {
654 bool on_off;
655
656 success = ParseVariableBool(opt1 + sizeof(prefix) - 1,
657 "-reuse-previous",
658 &on_off);
659 if (success)
660 {
661 reuse_previous = on_off ? TRI_YES : TRI_NO;
662 free(opt1);
663 opt1 = read_connect_arg(scan_state);
664 }
665 }
666
667 if (success) /* give up if reuse_previous was invalid */
668 {
669 opt2 = read_connect_arg(scan_state);
670 opt3 = read_connect_arg(scan_state);
671 opt4 = read_connect_arg(scan_state);
672
673 success = do_connect(reuse_previous, opt1, opt2, opt3, opt4);
674
675 free(opt2);
676 free(opt3);
677 free(opt4);
678 }
679 free(opt1);
680 }
681 else
682 ignore_slash_options(scan_state);
683
685}
686
687/*
688 * \cd -- change directory
689 */
690static backslashResult
691exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
692{
693 bool success = true;
694
695 if (active_branch)
696 {
697 char *opt = psql_scan_slash_option(scan_state,
698 OT_NORMAL, NULL, true);
699 char *dir;
700
701 if (opt)
702 dir = opt;
703 else
704 {
705#ifndef WIN32
706 /* This should match get_home_path() */
707 dir = getenv("HOME");
708 if (dir == NULL || dir[0] == '\0')
709 {
710 uid_t user_id = geteuid();
711 struct passwd *pw;
712
713 errno = 0; /* clear errno before call */
714 pw = getpwuid(user_id);
715 if (pw)
716 dir = pw->pw_dir;
717 else
718 {
719 pg_log_error("could not get home directory for user ID %ld: %s",
720 (long) user_id,
721 errno ? strerror(errno) : _("user does not exist"));
722 success = false;
723 }
724 }
725#else /* WIN32 */
726
727 /*
728 * On Windows, 'cd' without arguments prints the current
729 * directory, so if someone wants to code this here instead...
730 */
731 dir = "/";
732#endif /* WIN32 */
733 }
734
735 if (success &&
736 chdir(dir) < 0)
737 {
738 pg_log_error("\\%s: could not change directory to \"%s\": %m",
739 cmd, dir);
740 success = false;
741 }
742
743 free(opt);
744 }
745 else
746 ignore_slash_options(scan_state);
747
749}
750
751/*
752 * \close_prepared -- close a previously prepared statement
753 */
754static backslashResult
755exec_command_close_prepared(PsqlScanState scan_state, bool active_branch, const char *cmd)
756{
758
759 if (active_branch)
760 {
761 char *opt = psql_scan_slash_option(scan_state,
762 OT_NORMAL, NULL, false);
763
765
766 if (!opt)
767 {
768 pg_log_error("\\%s: missing required argument", cmd);
769 status = PSQL_CMD_ERROR;
770 }
771 else
772 {
773 pset.stmtName = opt;
775 status = PSQL_CMD_SEND;
776 }
777 }
778 else
779 ignore_slash_options(scan_state);
780
781 return status;
782}
783
784/*
785 * \conninfo -- display information about the current connection
786 */
787static backslashResult
788exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
789{
791 int rows,
792 cols;
793 char *db;
794 char *host;
795 bool print_hostaddr;
796 char *hostaddr;
797 char *protocol_version,
798 *backend_pid;
799 int ssl_in_use,
800 password_used,
801 gssapi_used;
802 int version_num;
803 char *paramval;
804
805 if (!active_branch)
806 return PSQL_CMD_SKIP_LINE;
807
808 db = PQdb(pset.db);
809 if (db == NULL)
810 {
811 printf(_("You are currently not connected to a database.\n"));
812 return PSQL_CMD_SKIP_LINE;
813 }
814
815 /* Get values for the parameters */
816 host = PQhost(pset.db);
817 hostaddr = PQhostaddr(pset.db);
818 version_num = PQfullProtocolVersion(pset.db);
819 protocol_version = psprintf("%d.%d", version_num / 10000,
820 version_num % 10000);
821 ssl_in_use = PQsslInUse(pset.db);
822 password_used = PQconnectionUsedPassword(pset.db);
823 gssapi_used = PQconnectionUsedGSSAPI(pset.db);
824 backend_pid = psprintf("%d", PQbackendPID(pset.db));
825
826 /* Only print hostaddr if it differs from host, and not if unixsock */
827 print_hostaddr = (!is_unixsock_path(host) &&
828 hostaddr && *hostaddr && strcmp(host, hostaddr) != 0);
829
830 /* Determine the exact number of rows to print */
831 rows = 12;
832 cols = 2;
833 if (ssl_in_use)
834 rows += 6;
835 if (print_hostaddr)
836 rows++;
837
838 /* Set it all up */
839 printTableInit(&cont, &pset.popt.topt, _("Connection Information"), cols, rows);
840 printTableAddHeader(&cont, _("Parameter"), true, 'l');
841 printTableAddHeader(&cont, _("Value"), true, 'l');
842
843 /* Database */
844 printTableAddCell(&cont, _("Database"), false, false);
845 printTableAddCell(&cont, db, false, false);
846
847 /* Client User */
848 printTableAddCell(&cont, _("Client User"), false, false);
849 printTableAddCell(&cont, PQuser(pset.db), false, false);
850
851 /* Host/hostaddr/socket */
852 if (is_unixsock_path(host))
853 {
854 /* hostaddr if specified overrides socket, so suppress the latter */
855 if (hostaddr && *hostaddr)
856 {
857 printTableAddCell(&cont, _("Host Address"), false, false);
858 printTableAddCell(&cont, hostaddr, false, false);
859 }
860 else
861 {
862 printTableAddCell(&cont, _("Socket Directory"), false, false);
863 printTableAddCell(&cont, host, false, false);
864 }
865 }
866 else
867 {
868 printTableAddCell(&cont, _("Host"), false, false);
869 printTableAddCell(&cont, host, false, false);
870 if (print_hostaddr)
871 {
872 printTableAddCell(&cont, _("Host Address"), false, false);
873 printTableAddCell(&cont, hostaddr, false, false);
874 }
875 }
876
877 /* Server Port */
878 printTableAddCell(&cont, _("Server Port"), false, false);
879 printTableAddCell(&cont, PQport(pset.db), false, false);
880
881 /* Options */
882 printTableAddCell(&cont, _("Options"), false, false);
883 printTableAddCell(&cont, PQoptions(pset.db), false, false);
884
885 /* Protocol Version */
886 printTableAddCell(&cont, _("Protocol Version"), false, false);
887 printTableAddCell(&cont, protocol_version, false, false);
888
889 /* Password Used */
890 printTableAddCell(&cont, _("Password Used"), false, false);
891 printTableAddCell(&cont, password_used ? _("true") : _("false"), false, false);
892
893 /* GSSAPI Authenticated */
894 printTableAddCell(&cont, _("GSSAPI Authenticated"), false, false);
895 printTableAddCell(&cont, gssapi_used ? _("true") : _("false"), false, false);
896
897 /* Backend PID */
898 printTableAddCell(&cont, _("Backend PID"), false, false);
899 printTableAddCell(&cont, backend_pid, false, false);
900
901 /* SSL Connection */
902 printTableAddCell(&cont, _("SSL Connection"), false, false);
903 printTableAddCell(&cont, ssl_in_use ? _("true") : _("false"), false, false);
904
905 /* SSL Information */
906 if (ssl_in_use)
907 {
908 char *library,
909 *protocol,
910 *key_bits,
911 *cipher,
912 *compression,
913 *alpn;
914
915 library = (char *) PQsslAttribute(pset.db, "library");
916 protocol = (char *) PQsslAttribute(pset.db, "protocol");
917 key_bits = (char *) PQsslAttribute(pset.db, "key_bits");
918 cipher = (char *) PQsslAttribute(pset.db, "cipher");
919 compression = (char *) PQsslAttribute(pset.db, "compression");
920 alpn = (char *) PQsslAttribute(pset.db, "alpn");
921
922 printTableAddCell(&cont, _("SSL Library"), false, false);
923 printTableAddCell(&cont, library ? library : _("unknown"), false, false);
924
925 printTableAddCell(&cont, _("SSL Protocol"), false, false);
926 printTableAddCell(&cont, protocol ? protocol : _("unknown"), false, false);
927
928 printTableAddCell(&cont, _("SSL Key Bits"), false, false);
929 printTableAddCell(&cont, key_bits ? key_bits : _("unknown"), false, false);
930
931 printTableAddCell(&cont, _("SSL Cipher"), false, false);
932 printTableAddCell(&cont, cipher ? cipher : _("unknown"), false, false);
933
934 printTableAddCell(&cont, _("SSL Compression"), false, false);
935 printTableAddCell(&cont, (compression && strcmp(compression, "off") != 0) ?
936 _("true") : _("false"), false, false);
937
938 printTableAddCell(&cont, _("ALPN"), false, false);
939 printTableAddCell(&cont, (alpn && alpn[0] != '\0') ? alpn : _("none"), false, false);
940 }
941
942 paramval = (char *) PQparameterStatus(pset.db, "is_superuser");
943 printTableAddCell(&cont, "Superuser", false, false);
944 printTableAddCell(&cont, paramval ? paramval : _("unknown"), false, false);
945
946 paramval = (char *) PQparameterStatus(pset.db, "in_hot_standby");
947 printTableAddCell(&cont, "Hot Standby", false, false);
948 printTableAddCell(&cont, paramval ? paramval : _("unknown"), false, false);
949
950 printTable(&cont, pset.queryFout, false, pset.logfile);
951 printTableCleanup(&cont);
952
953 pfree(protocol_version);
954 pfree(backend_pid);
955
956 return PSQL_CMD_SKIP_LINE;
957}
958
959/*
960 * \copy -- run a COPY command
961 */
962static backslashResult
963exec_command_copy(PsqlScanState scan_state, bool active_branch)
964{
965 bool success = true;
966
967 if (active_branch)
968 {
969 char *opt = psql_scan_slash_option(scan_state,
970 OT_WHOLE_LINE, NULL, false);
971
972 success = do_copy(opt);
973 free(opt);
974 }
975 else
976 ignore_slash_whole_line(scan_state);
977
979}
980
981/*
982 * \copyright -- print copyright notice
983 */
984static backslashResult
985exec_command_copyright(PsqlScanState scan_state, bool active_branch)
986{
987 if (active_branch)
989
990 return PSQL_CMD_SKIP_LINE;
991}
992
993/*
994 * \crosstabview -- execute a query and display result in crosstab
995 */
996static backslashResult
997exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
998{
1000
1001 if (active_branch)
1002 {
1003 int i;
1004
1005 for (i = 0; i < lengthof(pset.ctv_args); i++)
1006 pset.ctv_args[i] = psql_scan_slash_option(scan_state,
1007 OT_NORMAL, NULL, true);
1008 pset.crosstab_flag = true;
1009 status = PSQL_CMD_SEND;
1010 }
1011 else
1012 ignore_slash_options(scan_state);
1013
1014 return status;
1015}
1016
1017/*
1018 * \d* commands
1019 */
1020static backslashResult
1021exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
1022{
1024 bool success = true;
1025
1026 if (active_branch)
1027 {
1028 char *pattern;
1029 bool show_verbose,
1030 show_system;
1031 unsigned short int save_expanded;
1032
1033 /* We don't do SQLID reduction on the pattern yet */
1034 pattern = psql_scan_slash_option(scan_state,
1035 OT_NORMAL, NULL, true);
1036
1037 show_verbose = strchr(cmd, '+') ? true : false;
1038 show_system = strchr(cmd, 'S') ? true : false;
1039
1040 /*
1041 * The 'x' option turns expanded mode on for this command only. This
1042 * is allowed in all \d* commands, except \d by itself, since \dx is a
1043 * separate command. So the 'x' option cannot appear immediately after
1044 * \d, but it can appear after \d followed by other options.
1045 */
1046 save_expanded = pset.popt.topt.expanded;
1047 if (cmd[1] != '\0' && strchr(&cmd[2], 'x'))
1048 pset.popt.topt.expanded = 1;
1049
1050 switch (cmd[1])
1051 {
1052 case '\0':
1053 case '+':
1054 case 'S':
1055 if (pattern)
1056 success = describeTableDetails(pattern, show_verbose, show_system);
1057 else
1058 /* standard listing of interesting things */
1059 success = listTables("tvmsE", NULL, show_verbose, show_system);
1060 break;
1061 case 'A':
1062 {
1063 char *pattern2 = NULL;
1064
1065 if (pattern && cmd[2] != '\0' && cmd[2] != '+' && cmd[2] != 'x')
1066 pattern2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true);
1067
1068 switch (cmd[2])
1069 {
1070 case '\0':
1071 case '+':
1072 case 'x':
1073 success = describeAccessMethods(pattern, show_verbose);
1074 break;
1075 case 'c':
1076 success = listOperatorClasses(pattern, pattern2, show_verbose);
1077 break;
1078 case 'f':
1079 success = listOperatorFamilies(pattern, pattern2, show_verbose);
1080 break;
1081 case 'o':
1082 success = listOpFamilyOperators(pattern, pattern2, show_verbose);
1083 break;
1084 case 'p':
1085 success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
1086 break;
1087 default:
1088 status = PSQL_CMD_UNKNOWN;
1089 break;
1090 }
1091
1092 free(pattern2);
1093 }
1094 break;
1095 case 'a':
1096 success = describeAggregates(pattern, show_verbose, show_system);
1097 break;
1098 case 'b':
1099 success = describeTablespaces(pattern, show_verbose);
1100 break;
1101 case 'c':
1102 if (strncmp(cmd, "dconfig", 7) == 0)
1104 show_verbose,
1105 show_system);
1106 else
1107 success = listConversions(pattern,
1108 show_verbose,
1109 show_system);
1110 break;
1111 case 'C':
1112 success = listCasts(pattern, show_verbose);
1113 break;
1114 case 'd':
1115 if (strncmp(cmd, "ddp", 3) == 0)
1116 success = listDefaultACLs(pattern);
1117 else
1118 success = objectDescription(pattern, show_system);
1119 break;
1120 case 'D':
1121 success = listDomains(pattern, show_verbose, show_system);
1122 break;
1123 case 'f': /* function subsystem */
1124 switch (cmd[2])
1125 {
1126 case '\0':
1127 case '+':
1128 case 'S':
1129 case 'a':
1130 case 'n':
1131 case 'p':
1132 case 't':
1133 case 'w':
1134 case 'x':
1135 success = exec_command_dfo(scan_state, cmd, pattern,
1136 show_verbose, show_system);
1137 break;
1138 default:
1139 status = PSQL_CMD_UNKNOWN;
1140 break;
1141 }
1142 break;
1143 case 'g':
1144 /* no longer distinct from \du */
1145 success = describeRoles(pattern, show_verbose, show_system);
1146 break;
1147 case 'l':
1148 success = listLargeObjects(show_verbose);
1149 break;
1150 case 'L':
1151 success = listLanguages(pattern, show_verbose, show_system);
1152 break;
1153 case 'n':
1154 success = listSchemas(pattern, show_verbose, show_system);
1155 break;
1156 case 'o':
1157 success = exec_command_dfo(scan_state, cmd, pattern,
1158 show_verbose, show_system);
1159 break;
1160 case 'O':
1161 success = listCollations(pattern, show_verbose, show_system);
1162 break;
1163 case 'p':
1164 success = permissionsList(pattern, show_system);
1165 break;
1166 case 'P':
1167 {
1168 switch (cmd[2])
1169 {
1170 case '\0':
1171 case '+':
1172 case 't':
1173 case 'i':
1174 case 'n':
1175 case 'x':
1176 success = listPartitionedTables(&cmd[2], pattern, show_verbose);
1177 break;
1178 default:
1179 status = PSQL_CMD_UNKNOWN;
1180 break;
1181 }
1182 }
1183 break;
1184 case 'T':
1185 success = describeTypes(pattern, show_verbose, show_system);
1186 break;
1187 case 't':
1188 case 'v':
1189 case 'm':
1190 case 'i':
1191 case 's':
1192 case 'E':
1193 success = listTables(&cmd[1], pattern, show_verbose, show_system);
1194 break;
1195 case 'r':
1196 if (cmd[2] == 'd' && cmd[3] == 's')
1197 {
1198 char *pattern2 = NULL;
1199
1200 if (pattern)
1201 pattern2 = psql_scan_slash_option(scan_state,
1202 OT_NORMAL, NULL, true);
1203 success = listDbRoleSettings(pattern, pattern2);
1204
1205 free(pattern2);
1206 }
1207 else if (cmd[2] == 'g')
1208 success = describeRoleGrants(pattern, show_system);
1209 else
1210 status = PSQL_CMD_UNKNOWN;
1211 break;
1212 case 'R':
1213 switch (cmd[2])
1214 {
1215 case 'p':
1216 if (show_verbose)
1217 success = describePublications(pattern);
1218 else
1219 success = listPublications(pattern);
1220 break;
1221 case 's':
1222 success = describeSubscriptions(pattern, show_verbose);
1223 break;
1224 default:
1225 status = PSQL_CMD_UNKNOWN;
1226 }
1227 break;
1228 case 'u':
1229 success = describeRoles(pattern, show_verbose, show_system);
1230 break;
1231 case 'F': /* text search subsystem */
1232 switch (cmd[2])
1233 {
1234 case '\0':
1235 case '+':
1236 case 'x':
1237 success = listTSConfigs(pattern, show_verbose);
1238 break;
1239 case 'p':
1240 success = listTSParsers(pattern, show_verbose);
1241 break;
1242 case 'd':
1243 success = listTSDictionaries(pattern, show_verbose);
1244 break;
1245 case 't':
1246 success = listTSTemplates(pattern, show_verbose);
1247 break;
1248 default:
1249 status = PSQL_CMD_UNKNOWN;
1250 break;
1251 }
1252 break;
1253 case 'e': /* SQL/MED subsystem */
1254 switch (cmd[2])
1255 {
1256 case 's':
1257 success = listForeignServers(pattern, show_verbose);
1258 break;
1259 case 'u':
1260 success = listUserMappings(pattern, show_verbose);
1261 break;
1262 case 'w':
1263 success = listForeignDataWrappers(pattern, show_verbose);
1264 break;
1265 case 't':
1266 success = listForeignTables(pattern, show_verbose);
1267 break;
1268 default:
1269 status = PSQL_CMD_UNKNOWN;
1270 break;
1271 }
1272 break;
1273 case 'x': /* Extensions */
1274 if (show_verbose)
1275 success = listExtensionContents(pattern);
1276 else
1277 success = listExtensions(pattern);
1278 break;
1279 case 'X': /* Extended Statistics */
1280 success = listExtendedStats(pattern);
1281 break;
1282 case 'y': /* Event Triggers */
1283 success = listEventTriggers(pattern, show_verbose);
1284 break;
1285 default:
1286 status = PSQL_CMD_UNKNOWN;
1287 }
1288
1289 /* Restore original expanded mode */
1290 pset.popt.topt.expanded = save_expanded;
1291
1292 free(pattern);
1293 }
1294 else
1295 ignore_slash_options(scan_state);
1296
1297 if (!success)
1298 status = PSQL_CMD_ERROR;
1299
1300 return status;
1301}
1302
1303/* \df and \do; messy enough to split out of exec_command_d */
1304static bool
1305exec_command_dfo(PsqlScanState scan_state, const char *cmd,
1306 const char *pattern,
1307 bool show_verbose, bool show_system)
1308{
1309 bool success;
1310 char *arg_patterns[FUNC_MAX_ARGS];
1311 int num_arg_patterns = 0;
1312
1313 /* Collect argument-type patterns too */
1314 if (pattern) /* otherwise it was just \df or \do */
1315 {
1316 char *ap;
1317
1318 while ((ap = psql_scan_slash_option(scan_state,
1319 OT_NORMAL, NULL, true)) != NULL)
1320 {
1321 arg_patterns[num_arg_patterns++] = ap;
1322 if (num_arg_patterns >= FUNC_MAX_ARGS)
1323 break; /* protect limited-size array */
1324 }
1325 }
1326
1327 if (cmd[1] == 'f')
1328 success = describeFunctions(&cmd[2], pattern,
1329 arg_patterns, num_arg_patterns,
1330 show_verbose, show_system);
1331 else
1332 success = describeOperators(pattern,
1333 arg_patterns, num_arg_patterns,
1334 show_verbose, show_system);
1335
1336 while (--num_arg_patterns >= 0)
1337 free(arg_patterns[num_arg_patterns]);
1338
1339 return success;
1340}
1341
1342/*
1343 * \e or \edit -- edit the current query buffer, or edit a file and
1344 * make it the query buffer
1345 */
1346static backslashResult
1347exec_command_edit(PsqlScanState scan_state, bool active_branch,
1348 PQExpBuffer query_buf, PQExpBuffer previous_buf)
1349{
1351
1352 if (active_branch)
1353 {
1354 if (!query_buf)
1355 {
1356 pg_log_error("no query buffer");
1357 status = PSQL_CMD_ERROR;
1358 }
1359 else
1360 {
1361 char *fname;
1362 char *ln = NULL;
1363 int lineno = -1;
1364
1365 fname = psql_scan_slash_option(scan_state,
1366 OT_NORMAL, NULL, true);
1367 if (fname)
1368 {
1369 /* try to get separate lineno arg */
1370 ln = psql_scan_slash_option(scan_state,
1371 OT_NORMAL, NULL, true);
1372 if (ln == NULL)
1373 {
1374 /* only one arg; maybe it is lineno not fname */
1375 if (fname[0] &&
1376 strspn(fname, "0123456789") == strlen(fname))
1377 {
1378 /* all digits, so assume it is lineno */
1379 ln = fname;
1380 fname = NULL;
1381 }
1382 }
1383 }
1384 if (ln)
1385 {
1386 lineno = atoi(ln);
1387 if (lineno < 1)
1388 {
1389 pg_log_error("invalid line number: %s", ln);
1390 status = PSQL_CMD_ERROR;
1391 }
1392 }
1393 if (status != PSQL_CMD_ERROR)
1394 {
1395 bool discard_on_quit;
1396
1397 expand_tilde(&fname);
1398 if (fname)
1399 {
1401 /* Always clear buffer if the file isn't modified */
1402 discard_on_quit = true;
1403 }
1404 else
1405 {
1406 /*
1407 * If query_buf is empty, recall previous query for
1408 * editing. But in that case, the query buffer should be
1409 * emptied if editing doesn't modify the file.
1410 */
1411 discard_on_quit = copy_previous_query(query_buf,
1412 previous_buf);
1413 }
1414
1415 if (do_edit(fname, query_buf, lineno, discard_on_quit, NULL))
1416 status = PSQL_CMD_NEWEDIT;
1417 else
1418 status = PSQL_CMD_ERROR;
1419 }
1420
1421 /*
1422 * On error while editing or if specifying an incorrect line
1423 * number, reset the query buffer.
1424 */
1425 if (status == PSQL_CMD_ERROR)
1426 resetPQExpBuffer(query_buf);
1427
1428 free(fname);
1429 free(ln);
1430 }
1431 }
1432 else
1433 ignore_slash_options(scan_state);
1434
1435 return status;
1436}
1437
1438/*
1439 * \ef/\ev -- edit the named function/view, or
1440 * present a blank CREATE FUNCTION/VIEW template if no argument is given
1441 */
1442static backslashResult
1443exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
1444 PQExpBuffer query_buf, bool is_func)
1445{
1447
1448 if (active_branch)
1449 {
1450 char *obj_desc = psql_scan_slash_option(scan_state,
1452 NULL, true);
1453 int lineno = -1;
1454
1455 if (!query_buf)
1456 {
1457 pg_log_error("no query buffer");
1458 status = PSQL_CMD_ERROR;
1459 }
1460 else
1461 {
1462 Oid obj_oid = InvalidOid;
1464
1465 lineno = strip_lineno_from_objdesc(obj_desc);
1466 if (lineno == 0)
1467 {
1468 /* error already reported */
1469 status = PSQL_CMD_ERROR;
1470 }
1471 else if (!obj_desc)
1472 {
1473 /* set up an empty command to fill in */
1474 resetPQExpBuffer(query_buf);
1475 if (is_func)
1476 appendPQExpBufferStr(query_buf,
1477 "CREATE FUNCTION ( )\n"
1478 " RETURNS \n"
1479 " LANGUAGE \n"
1480 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1481 "AS $function$\n"
1482 "\n$function$\n");
1483 else
1484 appendPQExpBufferStr(query_buf,
1485 "CREATE VIEW AS\n"
1486 " SELECT \n"
1487 " -- something...\n");
1488 }
1489 else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
1490 {
1491 /* error already reported */
1492 status = PSQL_CMD_ERROR;
1493 }
1494 else if (!get_create_object_cmd(eot, obj_oid, query_buf))
1495 {
1496 /* error already reported */
1497 status = PSQL_CMD_ERROR;
1498 }
1499 else if (is_func && lineno > 0)
1500 {
1501 /*
1502 * lineno "1" should correspond to the first line of the
1503 * function body. We expect that pg_get_functiondef() will
1504 * emit that on a line beginning with "AS ", "BEGIN ", or
1505 * "RETURN ", and that there can be no such line before the
1506 * real start of the function body. Increment lineno by the
1507 * number of lines before that line, so that it becomes
1508 * relative to the first line of the function definition.
1509 */
1510 const char *lines = query_buf->data;
1511
1512 while (*lines != '\0')
1513 {
1514 if (strncmp(lines, "AS ", 3) == 0 ||
1515 strncmp(lines, "BEGIN ", 6) == 0 ||
1516 strncmp(lines, "RETURN ", 7) == 0)
1517 break;
1518 lineno++;
1519 /* find start of next line */
1520 lines = strchr(lines, '\n');
1521 if (!lines)
1522 break;
1523 lines++;
1524 }
1525 }
1526 }
1527
1528 if (status != PSQL_CMD_ERROR)
1529 {
1530 bool edited = false;
1531
1532 if (!do_edit(NULL, query_buf, lineno, true, &edited))
1533 status = PSQL_CMD_ERROR;
1534 else if (!edited)
1535 puts(_("No changes"));
1536 else
1537 status = PSQL_CMD_NEWEDIT;
1538 }
1539
1540 /*
1541 * On error while doing object lookup or while editing, or if
1542 * specifying an incorrect line number, reset the query buffer.
1543 */
1544 if (status == PSQL_CMD_ERROR)
1545 resetPQExpBuffer(query_buf);
1546
1547 free(obj_desc);
1548 }
1549 else
1550 ignore_slash_whole_line(scan_state);
1551
1552 return status;
1553}
1554
1555/*
1556 * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr
1557 */
1558static backslashResult
1559exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
1560{
1561 if (active_branch)
1562 {
1563 char *value;
1564 char quoted;
1565 bool no_newline = false;
1566 bool first = true;
1567 FILE *fout;
1568
1569 if (strcmp(cmd, "qecho") == 0)
1570 fout = pset.queryFout;
1571 else if (strcmp(cmd, "warn") == 0)
1572 fout = stderr;
1573 else
1574 fout = stdout;
1575
1576 while ((value = psql_scan_slash_option(scan_state,
1577 OT_NORMAL, &quoted, false)))
1578 {
1579 if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1580 no_newline = true;
1581 else
1582 {
1583 if (first)
1584 first = false;
1585 else
1586 fputc(' ', fout);
1587 fputs(value, fout);
1588 }
1589 free(value);
1590 }
1591 if (!no_newline)
1592 fputs("\n", fout);
1593 }
1594 else
1595 ignore_slash_options(scan_state);
1596
1597 return PSQL_CMD_SKIP_LINE;
1598}
1599
1600/*
1601 * \encoding -- set/show client side encoding
1602 */
1603static backslashResult
1604exec_command_encoding(PsqlScanState scan_state, bool active_branch)
1605{
1606 if (active_branch)
1607 {
1608 char *encoding = psql_scan_slash_option(scan_state,
1609 OT_NORMAL, NULL, false);
1610
1611 if (!encoding)
1612 {
1613 /* show encoding */
1615 }
1616 else
1617 {
1618 /* set encoding */
1619 if (PQsetClientEncoding(pset.db, encoding) == -1)
1620 pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1621 else
1622 {
1623 /* save encoding info into psql internal data */
1627 SetVariable(pset.vars, "ENCODING",
1629 }
1630 free(encoding);
1631 }
1632 }
1633 else
1634 ignore_slash_options(scan_state);
1635
1636 return PSQL_CMD_SKIP_LINE;
1637}
1638
1639/*
1640 * \errverbose -- display verbose message from last failed query
1641 */
1642static backslashResult
1643exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
1644{
1645 if (active_branch)
1646 {
1648 {
1649 char *msg;
1650
1654 if (msg)
1655 {
1656 pg_log_error("%s", msg);
1657 PQfreemem(msg);
1658 }
1659 else
1660 puts(_("out of memory"));
1661 }
1662 else
1663 puts(_("There is no previous error."));
1664 }
1665
1666 return PSQL_CMD_SKIP_LINE;
1667}
1668
1669/*
1670 * \f -- change field separator
1671 */
1672static backslashResult
1673exec_command_f(PsqlScanState scan_state, bool active_branch)
1674{
1675 bool success = true;
1676
1677 if (active_branch)
1678 {
1679 char *fname = psql_scan_slash_option(scan_state,
1680 OT_NORMAL, NULL, false);
1681
1682 success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
1683 free(fname);
1684 }
1685 else
1686 ignore_slash_options(scan_state);
1687
1689}
1690
1691/*
1692 * \flush -- call PQflush() on the connection
1693 */
1694static backslashResult
1695exec_command_flush(PsqlScanState scan_state, bool active_branch)
1696{
1698
1699 if (active_branch)
1700 {
1702 status = PSQL_CMD_SEND;
1703 }
1704 else
1705 ignore_slash_options(scan_state);
1706
1707 return status;
1708}
1709
1710/*
1711 * \flushrequest -- call PQsendFlushRequest() on the connection
1712 */
1713static backslashResult
1714exec_command_flushrequest(PsqlScanState scan_state, bool active_branch)
1715{
1717
1718 if (active_branch)
1719 {
1721 status = PSQL_CMD_SEND;
1722 }
1723 else
1724 ignore_slash_options(scan_state);
1725
1726 return status;
1727}
1728
1729/*
1730 * \g [(pset-option[=pset-value] ...)] [filename/shell-command]
1731 * \gx [(pset-option[=pset-value] ...)] [filename/shell-command]
1732 *
1733 * Send the current query. If pset options are specified, they are made
1734 * active just for this query. If a filename or pipe command is given,
1735 * the query output goes there. \gx implicitly sets "expanded=on" along
1736 * with any other pset options that are specified.
1737 */
1738static backslashResult
1739exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
1740{
1742 char *fname;
1743
1744 /*
1745 * Because the option processing for this is fairly complicated, we do it
1746 * and then decide whether the branch is active.
1747 */
1748 fname = psql_scan_slash_option(scan_state,
1749 OT_FILEPIPE, NULL, false);
1750
1751 if (fname && fname[0] == '(')
1752 {
1753 /* Consume pset options through trailing ')' ... */
1754 status = process_command_g_options(fname + 1, scan_state,
1755 active_branch, cmd);
1756 free(fname);
1757 /* ... and again attempt to scan the filename. */
1758 fname = psql_scan_slash_option(scan_state,
1759 OT_FILEPIPE, NULL, false);
1760 }
1761
1762 if (status == PSQL_CMD_SKIP_LINE && active_branch)
1763 {
1765 {
1766 pg_log_error("\\%s not allowed in pipeline mode", cmd);
1768 free(fname);
1769 return PSQL_CMD_ERROR;
1770 }
1771
1772 if (!fname)
1773 pset.gfname = NULL;
1774 else
1775 {
1776 expand_tilde(&fname);
1777 pset.gfname = pg_strdup(fname);
1778 }
1779 if (strcmp(cmd, "gx") == 0)
1780 {
1781 /* save settings if not done already, then force expanded=on */
1782 if (pset.gsavepopt == NULL)
1784 pset.popt.topt.expanded = 1;
1785 }
1786 status = PSQL_CMD_SEND;
1787 }
1788
1789 free(fname);
1790
1791 return status;
1792}
1793
1794/*
1795 * Process parenthesized pset options for \g
1796 *
1797 * Note: okay to modify first_option, but not to free it; caller does that
1798 */
1799static backslashResult
1800process_command_g_options(char *first_option, PsqlScanState scan_state,
1801 bool active_branch, const char *cmd)
1802{
1803 bool success = true;
1804 bool found_r_paren = false;
1805
1806 do
1807 {
1808 char *option;
1809 size_t optlen;
1810
1811 /* If not first time through, collect a new option */
1812 if (first_option)
1813 option = first_option;
1814 else
1815 {
1816 option = psql_scan_slash_option(scan_state,
1817 OT_NORMAL, NULL, false);
1818 if (!option)
1819 {
1820 if (active_branch)
1821 {
1822 pg_log_error("\\%s: missing right parenthesis", cmd);
1823 success = false;
1824 }
1825 break;
1826 }
1827 }
1828
1829 /* Check for terminating right paren, and remove it from string */
1830 optlen = strlen(option);
1831 if (optlen > 0 && option[optlen - 1] == ')')
1832 {
1833 option[--optlen] = '\0';
1834 found_r_paren = true;
1835 }
1836
1837 /* If there was anything besides parentheses, parse/execute it */
1838 if (optlen > 0)
1839 {
1840 /* We can have either "name" or "name=value" */
1841 char *valptr = strchr(option, '=');
1842
1843 if (valptr)
1844 *valptr++ = '\0';
1845 if (active_branch)
1846 {
1847 /* save settings if not done already, then apply option */
1848 if (pset.gsavepopt == NULL)
1850 success &= do_pset(option, valptr, &pset.popt, true);
1851 }
1852 }
1853
1854 /* Clean up after this option. We should not free first_option. */
1855 if (first_option)
1856 first_option = NULL;
1857 else
1858 free(option);
1859 } while (!found_r_paren);
1860
1861 /* If we failed after already changing some options, undo side-effects */
1862 if (!success && active_branch && pset.gsavepopt)
1863 {
1865 pset.gsavepopt = NULL;
1866 }
1867
1869}
1870
1871/*
1872 * \gdesc -- describe query result
1873 */
1874static backslashResult
1875exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
1876{
1878
1879 if (active_branch)
1880 {
1881 pset.gdesc_flag = true;
1882 status = PSQL_CMD_SEND;
1883 }
1884
1885 return status;
1886}
1887
1888/*
1889 * \getenv -- set variable from environment variable
1890 */
1891static backslashResult
1892exec_command_getenv(PsqlScanState scan_state, bool active_branch,
1893 const char *cmd)
1894{
1895 bool success = true;
1896
1897 if (active_branch)
1898 {
1899 char *myvar = psql_scan_slash_option(scan_state,
1900 OT_NORMAL, NULL, false);
1901 char *envvar = psql_scan_slash_option(scan_state,
1902 OT_NORMAL, NULL, false);
1903
1904 if (!myvar || !envvar)
1905 {
1906 pg_log_error("\\%s: missing required argument", cmd);
1907 success = false;
1908 }
1909 else
1910 {
1911 char *envval = getenv(envvar);
1912
1913 if (envval && !SetVariable(pset.vars, myvar, envval))
1914 success = false;
1915 }
1916 free(myvar);
1917 free(envvar);
1918 }
1919 else
1920 ignore_slash_options(scan_state);
1921
1923}
1924
1925/*
1926 * \getresults -- read results
1927 */
1928static backslashResult
1929exec_command_getresults(PsqlScanState scan_state, bool active_branch)
1930{
1932
1933 if (active_branch)
1934 {
1935 char *opt;
1936 int num_results;
1937
1939 status = PSQL_CMD_SEND;
1940 opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
1941
1943 if (opt != NULL)
1944 {
1945 num_results = atoi(opt);
1946 if (num_results < 0)
1947 {
1948 pg_log_error("\\getresults: invalid number of requested results");
1949 return PSQL_CMD_ERROR;
1950 }
1951 pset.requested_results = num_results;
1952 }
1953 }
1954 else
1955 ignore_slash_options(scan_state);
1956
1957 return status;
1958}
1959
1960
1961/*
1962 * \gexec -- send query and execute each field of result
1963 */
1964static backslashResult
1965exec_command_gexec(PsqlScanState scan_state, bool active_branch)
1966{
1968
1969 if (active_branch)
1970 {
1972 {
1973 pg_log_error("\\%s not allowed in pipeline mode", "gexec");
1975 return PSQL_CMD_ERROR;
1976 }
1977 pset.gexec_flag = true;
1978 status = PSQL_CMD_SEND;
1979 }
1980
1981 return status;
1982}
1983
1984/*
1985 * \gset [prefix] -- send query and store result into variables
1986 */
1987static backslashResult
1988exec_command_gset(PsqlScanState scan_state, bool active_branch)
1989{
1991
1992 if (active_branch)
1993 {
1994 char *prefix = psql_scan_slash_option(scan_state,
1995 OT_NORMAL, NULL, false);
1996
1998 {
1999 pg_log_error("\\%s not allowed in pipeline mode", "gset");
2001 return PSQL_CMD_ERROR;
2002 }
2003
2004 if (prefix)
2005 pset.gset_prefix = prefix;
2006 else
2007 {
2008 /* we must set a non-NULL prefix to trigger storing */
2010 }
2011 /* gset_prefix is freed later */
2012 status = PSQL_CMD_SEND;
2013 }
2014 else
2015 ignore_slash_options(scan_state);
2016
2017 return status;
2018}
2019
2020/*
2021 * \help [topic] -- print help about SQL commands
2022 */
2023static backslashResult
2024exec_command_help(PsqlScanState scan_state, bool active_branch)
2025{
2026 if (active_branch)
2027 {
2028 char *opt = psql_scan_slash_option(scan_state,
2029 OT_WHOLE_LINE, NULL, true);
2030
2031 helpSQL(opt, pset.popt.topt.pager);
2032 free(opt);
2033 }
2034 else
2035 ignore_slash_whole_line(scan_state);
2036
2037 return PSQL_CMD_SKIP_LINE;
2038}
2039
2040/*
2041 * \H and \html -- toggle HTML formatting
2042 */
2043static backslashResult
2044exec_command_html(PsqlScanState scan_state, bool active_branch)
2045{
2046 bool success = true;
2047
2048 if (active_branch)
2049 {
2051 success = do_pset("format", "html", &pset.popt, pset.quiet);
2052 else
2053 success = do_pset("format", "aligned", &pset.popt, pset.quiet);
2054 }
2055
2057}
2058
2059/*
2060 * \i and \ir -- include a file
2061 */
2062static backslashResult
2063exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
2064{
2065 bool success = true;
2066
2067 if (active_branch)
2068 {
2069 char *fname = psql_scan_slash_option(scan_state,
2070 OT_NORMAL, NULL, true);
2071
2072 if (!fname)
2073 {
2074 pg_log_error("\\%s: missing required argument", cmd);
2075 success = false;
2076 }
2077 else
2078 {
2079 bool include_relative;
2080
2081 include_relative = (strcmp(cmd, "ir") == 0
2082 || strcmp(cmd, "include_relative") == 0);
2083 expand_tilde(&fname);
2084 success = (process_file(fname, include_relative) == EXIT_SUCCESS);
2085 free(fname);
2086 }
2087 }
2088 else
2089 ignore_slash_options(scan_state);
2090
2092}
2093
2094/*
2095 * \if <expr> -- beginning of an \if..\endif block
2096 *
2097 * <expr> is parsed as a boolean expression. Invalid expressions will emit a
2098 * warning and be treated as false. Statements that follow a false expression
2099 * will be parsed but ignored. Note that in the case where an \if statement
2100 * is itself within an inactive section of a block, then the entire inner
2101 * \if..\endif block will be parsed but ignored.
2102 */
2103static backslashResult
2105 PQExpBuffer query_buf)
2106{
2107 if (conditional_active(cstack))
2108 {
2109 /*
2110 * First, push a new active stack entry; this ensures that the lexer
2111 * will perform variable substitution and backtick evaluation while
2112 * scanning the expression. (That should happen anyway, since we know
2113 * we're in an active outer branch, but let's be sure.)
2114 */
2116
2117 /* Remember current query state in case we need to restore later */
2118 save_query_text_state(scan_state, cstack, query_buf);
2119
2120 /*
2121 * Evaluate the expression; if it's false, change to inactive state.
2122 */
2123 if (!is_true_boolean_expression(scan_state, "\\if expression"))
2125 }
2126 else
2127 {
2128 /*
2129 * We're within an inactive outer branch, so this entire \if block
2130 * will be ignored. We don't want to evaluate the expression, so push
2131 * the "ignored" stack state before scanning it.
2132 */
2134
2135 /* Remember current query state in case we need to restore later */
2136 save_query_text_state(scan_state, cstack, query_buf);
2137
2138 ignore_boolean_expression(scan_state);
2139 }
2140
2141 return PSQL_CMD_SKIP_LINE;
2142}
2143
2144/*
2145 * \elif <expr> -- alternative branch in an \if..\endif block
2146 *
2147 * <expr> is evaluated the same as in \if <expr>.
2148 */
2149static backslashResult
2151 PQExpBuffer query_buf)
2152{
2153 bool success = true;
2154
2155 switch (conditional_stack_peek(cstack))
2156 {
2157 case IFSTATE_TRUE:
2158
2159 /*
2160 * Just finished active branch of this \if block. Update saved
2161 * state so we will keep whatever data was put in query_buf by the
2162 * active branch.
2163 */
2164 save_query_text_state(scan_state, cstack, query_buf);
2165
2166 /*
2167 * Discard \elif expression and ignore the rest until \endif.
2168 * Switch state before reading expression to ensure proper lexer
2169 * behavior.
2170 */
2172 ignore_boolean_expression(scan_state);
2173 break;
2174 case IFSTATE_FALSE:
2175
2176 /*
2177 * Discard any query text added by the just-skipped branch.
2178 */
2179 discard_query_text(scan_state, cstack, query_buf);
2180
2181 /*
2182 * Have not yet found a true expression in this \if block, so this
2183 * might be the first. We have to change state before examining
2184 * the expression, or the lexer won't do the right thing.
2185 */
2187 if (!is_true_boolean_expression(scan_state, "\\elif expression"))
2189 break;
2190 case IFSTATE_IGNORED:
2191
2192 /*
2193 * Discard any query text added by the just-skipped branch.
2194 */
2195 discard_query_text(scan_state, cstack, query_buf);
2196
2197 /*
2198 * Skip expression and move on. Either the \if block already had
2199 * an active section, or whole block is being skipped.
2200 */
2201 ignore_boolean_expression(scan_state);
2202 break;
2203 case IFSTATE_ELSE_TRUE:
2204 case IFSTATE_ELSE_FALSE:
2205 pg_log_error("\\elif: cannot occur after \\else");
2206 success = false;
2207 break;
2208 case IFSTATE_NONE:
2209 /* no \if to elif from */
2210 pg_log_error("\\elif: no matching \\if");
2211 success = false;
2212 break;
2213 }
2214
2216}
2217
2218/*
2219 * \else -- final alternative in an \if..\endif block
2220 *
2221 * Statements within an \else branch will only be executed if
2222 * all previous \if and \elif expressions evaluated to false
2223 * and the block was not itself being ignored.
2224 */
2225static backslashResult
2227 PQExpBuffer query_buf)
2228{
2229 bool success = true;
2230
2231 switch (conditional_stack_peek(cstack))
2232 {
2233 case IFSTATE_TRUE:
2234
2235 /*
2236 * Just finished active branch of this \if block. Update saved
2237 * state so we will keep whatever data was put in query_buf by the
2238 * active branch.
2239 */
2240 save_query_text_state(scan_state, cstack, query_buf);
2241
2242 /* Now skip the \else branch */
2244 break;
2245 case IFSTATE_FALSE:
2246
2247 /*
2248 * Discard any query text added by the just-skipped branch.
2249 */
2250 discard_query_text(scan_state, cstack, query_buf);
2251
2252 /*
2253 * We've not found any true \if or \elif expression, so execute
2254 * the \else branch.
2255 */
2257 break;
2258 case IFSTATE_IGNORED:
2259
2260 /*
2261 * Discard any query text added by the just-skipped branch.
2262 */
2263 discard_query_text(scan_state, cstack, query_buf);
2264
2265 /*
2266 * Either we previously processed the active branch of this \if,
2267 * or the whole \if block is being skipped. Either way, skip the
2268 * \else branch.
2269 */
2271 break;
2272 case IFSTATE_ELSE_TRUE:
2273 case IFSTATE_ELSE_FALSE:
2274 pg_log_error("\\else: cannot occur after \\else");
2275 success = false;
2276 break;
2277 case IFSTATE_NONE:
2278 /* no \if to else from */
2279 pg_log_error("\\else: no matching \\if");
2280 success = false;
2281 break;
2282 }
2283
2285}
2286
2287/*
2288 * \endif -- ends an \if...\endif block
2289 */
2290static backslashResult
2292 PQExpBuffer query_buf)
2293{
2294 bool success = true;
2295
2296 switch (conditional_stack_peek(cstack))
2297 {
2298 case IFSTATE_TRUE:
2299 case IFSTATE_ELSE_TRUE:
2300 /* Close the \if block, keeping the query text */
2302 Assert(success);
2303 break;
2304 case IFSTATE_FALSE:
2305 case IFSTATE_IGNORED:
2306 case IFSTATE_ELSE_FALSE:
2307
2308 /*
2309 * Discard any query text added by the just-skipped branch.
2310 */
2311 discard_query_text(scan_state, cstack, query_buf);
2312
2313 /* Close the \if block */
2315 Assert(success);
2316 break;
2317 case IFSTATE_NONE:
2318 /* no \if to end */
2319 pg_log_error("\\endif: no matching \\if");
2320 success = false;
2321 break;
2322 }
2323
2325}
2326
2327/*
2328 * \l -- list databases
2329 */
2330static backslashResult
2331exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
2332{
2333 bool success = true;
2334
2335 if (active_branch)
2336 {
2337 char *pattern;
2338 bool show_verbose;
2339 unsigned short int save_expanded;
2340
2341 pattern = psql_scan_slash_option(scan_state,
2342 OT_NORMAL, NULL, true);
2343
2344 show_verbose = strchr(cmd, '+') ? true : false;
2345
2346 /* if 'x' option specified, force expanded mode */
2347 save_expanded = pset.popt.topt.expanded;
2348 if (strchr(cmd, 'x'))
2349 pset.popt.topt.expanded = 1;
2350
2351 success = listAllDbs(pattern, show_verbose);
2352
2353 /* restore original expanded mode */
2354 pset.popt.topt.expanded = save_expanded;
2355
2356 free(pattern);
2357 }
2358 else
2359 ignore_slash_options(scan_state);
2360
2362}
2363
2364/*
2365 * \lo_* -- large object operations
2366 */
2367static backslashResult
2368exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
2369{
2371 bool success = true;
2372
2373 if (active_branch)
2374 {
2375 char *opt1,
2376 *opt2;
2377
2378 opt1 = psql_scan_slash_option(scan_state,
2379 OT_NORMAL, NULL, true);
2380 opt2 = psql_scan_slash_option(scan_state,
2381 OT_NORMAL, NULL, true);
2382
2383 if (strcmp(cmd + 3, "export") == 0)
2384 {
2385 if (!opt2)
2386 {
2387 pg_log_error("\\%s: missing required argument", cmd);
2388 success = false;
2389 }
2390 else
2391 {
2392 expand_tilde(&opt2);
2393 success = do_lo_export(opt1, opt2);
2394 }
2395 }
2396
2397 else if (strcmp(cmd + 3, "import") == 0)
2398 {
2399 if (!opt1)
2400 {
2401 pg_log_error("\\%s: missing required argument", cmd);
2402 success = false;
2403 }
2404 else
2405 {
2406 expand_tilde(&opt1);
2407 success = do_lo_import(opt1, opt2);
2408 }
2409 }
2410
2411 else if (strncmp(cmd + 3, "list", 4) == 0)
2412 {
2413 bool show_verbose;
2414 unsigned short int save_expanded;
2415
2416 show_verbose = strchr(cmd, '+') ? true : false;
2417
2418 /* if 'x' option specified, force expanded mode */
2419 save_expanded = pset.popt.topt.expanded;
2420 if (strchr(cmd, 'x'))
2421 pset.popt.topt.expanded = 1;
2422
2423 success = listLargeObjects(show_verbose);
2424
2425 /* restore original expanded mode */
2426 pset.popt.topt.expanded = save_expanded;
2427 }
2428
2429 else if (strcmp(cmd + 3, "unlink") == 0)
2430 {
2431 if (!opt1)
2432 {
2433 pg_log_error("\\%s: missing required argument", cmd);
2434 success = false;
2435 }
2436 else
2437 success = do_lo_unlink(opt1);
2438 }
2439
2440 else
2441 status = PSQL_CMD_UNKNOWN;
2442
2443 free(opt1);
2444 free(opt2);
2445 }
2446 else
2447 ignore_slash_options(scan_state);
2448
2449 if (!success)
2450 status = PSQL_CMD_ERROR;
2451
2452 return status;
2453}
2454
2455/*
2456 * \o -- set query output
2457 */
2458static backslashResult
2459exec_command_out(PsqlScanState scan_state, bool active_branch)
2460{
2461 bool success = true;
2462
2463 if (active_branch)
2464 {
2465 char *fname = psql_scan_slash_option(scan_state,
2466 OT_FILEPIPE, NULL, true);
2467
2468 expand_tilde(&fname);
2469 success = setQFout(fname);
2470 free(fname);
2471 }
2472 else
2473 ignore_slash_filepipe(scan_state);
2474
2476}
2477
2478/*
2479 * \p -- print the current query buffer
2480 */
2481static backslashResult
2482exec_command_print(PsqlScanState scan_state, bool active_branch,
2483 PQExpBuffer query_buf, PQExpBuffer previous_buf)
2484{
2485 if (active_branch)
2486 {
2487 /*
2488 * We want to print the same thing \g would execute, but not to change
2489 * the query buffer state; so we can't use copy_previous_query().
2490 * Also, beware of possibility that buffer pointers are NULL.
2491 */
2492 if (query_buf && query_buf->len > 0)
2493 puts(query_buf->data);
2494 else if (previous_buf && previous_buf->len > 0)
2495 puts(previous_buf->data);
2496 else if (!pset.quiet)
2497 puts(_("Query buffer is empty."));
2498 fflush(stdout);
2499 }
2500
2501 return PSQL_CMD_SKIP_LINE;
2502}
2503
2504/*
2505 * \parse -- parse query
2506 */
2507static backslashResult
2508exec_command_parse(PsqlScanState scan_state, bool active_branch,
2509 const char *cmd)
2510{
2512
2513 if (active_branch)
2514 {
2515 char *opt = psql_scan_slash_option(scan_state,
2516 OT_NORMAL, NULL, false);
2517
2519
2520 if (!opt)
2521 {
2522 pg_log_error("\\%s: missing required argument", cmd);
2523 status = PSQL_CMD_ERROR;
2524 }
2525 else
2526 {
2527 pset.stmtName = opt;
2529 status = PSQL_CMD_SEND;
2530 }
2531 }
2532 else
2533 ignore_slash_options(scan_state);
2534
2535 return status;
2536}
2537
2538/*
2539 * \password -- set user password
2540 */
2541static backslashResult
2542exec_command_password(PsqlScanState scan_state, bool active_branch)
2543{
2544 bool success = true;
2545
2546 if (active_branch)
2547 {
2548 char *user = psql_scan_slash_option(scan_state,
2549 OT_SQLID, NULL, true);
2550 char *pw1 = NULL;
2551 char *pw2 = NULL;
2553 PromptInterruptContext prompt_ctx;
2554
2555 if (user == NULL)
2556 {
2557 /* By default, the command applies to CURRENT_USER */
2558 PGresult *res;
2559
2560 res = PSQLexec("SELECT CURRENT_USER");
2561 if (!res)
2562 return PSQL_CMD_ERROR;
2563
2564 user = pg_strdup(PQgetvalue(res, 0, 0));
2565 PQclear(res);
2566 }
2567
2568 /* Set up to let SIGINT cancel simple_prompt_extended() */
2569 prompt_ctx.jmpbuf = sigint_interrupt_jmp;
2570 prompt_ctx.enabled = &sigint_interrupt_enabled;
2571 prompt_ctx.canceled = false;
2572
2574 printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
2575
2576 pw1 = simple_prompt_extended(buf.data, false, &prompt_ctx);
2577 if (!prompt_ctx.canceled)
2578 pw2 = simple_prompt_extended("Enter it again: ", false, &prompt_ctx);
2579
2580 if (prompt_ctx.canceled)
2581 {
2582 /* fail silently */
2583 success = false;
2584 }
2585 else if (strcmp(pw1, pw2) != 0)
2586 {
2587 pg_log_error("Passwords didn't match.");
2588 success = false;
2589 }
2590 else
2591 {
2592 PGresult *res = PQchangePassword(pset.db, user, pw1);
2593
2594 if (PQresultStatus(res) != PGRES_COMMAND_OK)
2595 {
2597 success = false;
2598 }
2599
2600 PQclear(res);
2601 }
2602
2603 free(user);
2604 free(pw1);
2605 free(pw2);
2607 }
2608 else
2609 ignore_slash_options(scan_state);
2610
2612}
2613
2614/*
2615 * \prompt -- prompt and set variable
2616 */
2617static backslashResult
2618exec_command_prompt(PsqlScanState scan_state, bool active_branch,
2619 const char *cmd)
2620{
2621 bool success = true;
2622
2623 if (active_branch)
2624 {
2625 char *opt,
2626 *prompt_text = NULL;
2627 char *arg1,
2628 *arg2;
2629
2630 arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2631 arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2632
2633 if (!arg1)
2634 {
2635 pg_log_error("\\%s: missing required argument", cmd);
2636 success = false;
2637 }
2638 else
2639 {
2640 char *result;
2641 PromptInterruptContext prompt_ctx;
2642
2643 /* Set up to let SIGINT cancel simple_prompt_extended() */
2644 prompt_ctx.jmpbuf = sigint_interrupt_jmp;
2645 prompt_ctx.enabled = &sigint_interrupt_enabled;
2646 prompt_ctx.canceled = false;
2647
2648 if (arg2)
2649 {
2650 prompt_text = arg1;
2651 opt = arg2;
2652 }
2653 else
2654 opt = arg1;
2655
2656 if (!pset.inputfile)
2657 {
2658 result = simple_prompt_extended(prompt_text, true, &prompt_ctx);
2659 }
2660 else
2661 {
2662 if (prompt_text)
2663 {
2664 fputs(prompt_text, stdout);
2665 fflush(stdout);
2666 }
2667 result = gets_fromFile(stdin);
2668 if (!result)
2669 {
2670 pg_log_error("\\%s: could not read value for variable",
2671 cmd);
2672 success = false;
2673 }
2674 }
2675
2676 if (prompt_ctx.canceled ||
2677 (result && !SetVariable(pset.vars, opt, result)))
2678 success = false;
2679
2680 free(result);
2681 free(prompt_text);
2682 free(opt);
2683 }
2684 }
2685 else
2686 ignore_slash_options(scan_state);
2687
2689}
2690
2691/*
2692 * \pset -- set printing parameters
2693 */
2694static backslashResult
2695exec_command_pset(PsqlScanState scan_state, bool active_branch)
2696{
2697 bool success = true;
2698
2699 if (active_branch)
2700 {
2701 char *opt0 = psql_scan_slash_option(scan_state,
2702 OT_NORMAL, NULL, false);
2703 char *opt1 = psql_scan_slash_option(scan_state,
2704 OT_NORMAL, NULL, false);
2705
2706 if (!opt0)
2707 {
2708 /* list all variables */
2709
2710 int i;
2711 static const char *const my_list[] = {
2712 "border", "columns", "csv_fieldsep",
2713 "display_false", "display_true", "expanded", "fieldsep",
2714 "fieldsep_zero", "footer", "format", "linestyle", "null",
2715 "numericlocale", "pager", "pager_min_lines",
2716 "recordsep", "recordsep_zero",
2717 "tableattr", "title", "tuples_only",
2718 "unicode_border_linestyle",
2719 "unicode_column_linestyle",
2720 "unicode_header_linestyle",
2721 "xheader_width",
2722 NULL
2723 };
2724
2725 for (i = 0; my_list[i] != NULL; i++)
2726 {
2727 char *val = pset_value_string(my_list[i], &pset.popt);
2728
2729 printf("%-24s %s\n", my_list[i], val);
2730 free(val);
2731 }
2732
2733 success = true;
2734 }
2735 else
2736 success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
2737
2738 free(opt0);
2739 free(opt1);
2740 }
2741 else
2742 ignore_slash_options(scan_state);
2743
2745}
2746
2747/*
2748 * \q or \quit -- exit psql
2749 */
2750static backslashResult
2751exec_command_quit(PsqlScanState scan_state, bool active_branch)
2752{
2754
2755 if (active_branch)
2756 status = PSQL_CMD_TERMINATE;
2757
2758 return status;
2759}
2760
2761/*
2762 * \r -- reset (clear) the query buffer
2763 */
2764static backslashResult
2765exec_command_reset(PsqlScanState scan_state, bool active_branch,
2766 PQExpBuffer query_buf)
2767{
2768 if (active_branch)
2769 {
2770 resetPQExpBuffer(query_buf);
2771 psql_scan_reset(scan_state);
2772 if (!pset.quiet)
2773 puts(_("Query buffer reset (cleared)."));
2774 }
2775
2776 return PSQL_CMD_SKIP_LINE;
2777}
2778
2779/*
2780 * \restrict -- enter "restricted mode" with the provided key
2781 */
2782static backslashResult
2783exec_command_restrict(PsqlScanState scan_state, bool active_branch,
2784 const char *cmd)
2785{
2786 if (active_branch)
2787 {
2788 char *opt;
2789
2791
2792 opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true);
2793 if (opt == NULL || opt[0] == '\0')
2794 {
2795 pg_log_error("\\%s: missing required argument", cmd);
2796 return PSQL_CMD_ERROR;
2797 }
2798
2799 restrict_key = pstrdup(opt);
2800 restricted = true;
2801 }
2802 else
2803 ignore_slash_options(scan_state);
2804
2805 return PSQL_CMD_SKIP_LINE;
2806}
2807
2808/*
2809 * \s -- save history in a file or show it on the screen
2810 */
2811static backslashResult
2812exec_command_s(PsqlScanState scan_state, bool active_branch)
2813{
2814 bool success = true;
2815
2816 if (active_branch)
2817 {
2818 char *fname = psql_scan_slash_option(scan_state,
2819 OT_NORMAL, NULL, true);
2820
2821 expand_tilde(&fname);
2823 if (success && !pset.quiet && fname)
2824 printf(_("Wrote history to file \"%s\".\n"), fname);
2825 if (!fname)
2826 putchar('\n');
2827 free(fname);
2828 }
2829 else
2830 ignore_slash_options(scan_state);
2831
2833}
2834
2835/*
2836 * \sendpipeline -- send an extended query to an ongoing pipeline
2837 */
2838static backslashResult
2839exec_command_sendpipeline(PsqlScanState scan_state, bool active_branch)
2840{
2842
2843 if (active_branch)
2844 {
2846 {
2849 {
2850 status = PSQL_CMD_SEND;
2851 }
2852 else
2853 {
2854 pg_log_error("\\sendpipeline must be used after \\bind or \\bind_named");
2856 return PSQL_CMD_ERROR;
2857 }
2858 }
2859 else
2860 {
2861 pg_log_error("\\sendpipeline not allowed outside of pipeline mode");
2863 return PSQL_CMD_ERROR;
2864 }
2865 }
2866 else
2867 ignore_slash_options(scan_state);
2868
2869 return status;
2870}
2871
2872/*
2873 * \set -- set variable
2874 */
2875static backslashResult
2876exec_command_set(PsqlScanState scan_state, bool active_branch)
2877{
2878 bool success = true;
2879
2880 if (active_branch)
2881 {
2882 char *opt0 = psql_scan_slash_option(scan_state,
2883 OT_NORMAL, NULL, false);
2884
2885 if (!opt0)
2886 {
2887 /* list all variables */
2889 success = true;
2890 }
2891 else
2892 {
2893 /*
2894 * Set variable to the concatenation of the arguments.
2895 */
2896 char *newval;
2897 char *opt;
2898
2899 opt = psql_scan_slash_option(scan_state,
2900 OT_NORMAL, NULL, false);
2901 newval = pg_strdup(opt ? opt : "");
2902 free(opt);
2903
2904 while ((opt = psql_scan_slash_option(scan_state,
2905 OT_NORMAL, NULL, false)))
2906 {
2907 newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
2908 strcat(newval, opt);
2909 free(opt);
2910 }
2911
2912 if (!SetVariable(pset.vars, opt0, newval))
2913 success = false;
2914
2915 free(newval);
2916 }
2917 free(opt0);
2918 }
2919 else
2920 ignore_slash_options(scan_state);
2921
2923}
2924
2925/*
2926 * \setenv -- set environment variable
2927 */
2928static backslashResult
2929exec_command_setenv(PsqlScanState scan_state, bool active_branch,
2930 const char *cmd)
2931{
2932 bool success = true;
2933
2934 if (active_branch)
2935 {
2936 char *envvar = psql_scan_slash_option(scan_state,
2937 OT_NORMAL, NULL, false);
2938 char *envval = psql_scan_slash_option(scan_state,
2939 OT_NORMAL, NULL, false);
2940
2941 if (!envvar)
2942 {
2943 pg_log_error("\\%s: missing required argument", cmd);
2944 success = false;
2945 }
2946 else if (strchr(envvar, '=') != NULL)
2947 {
2948 pg_log_error("\\%s: environment variable name must not contain \"=\"",
2949 cmd);
2950 success = false;
2951 }
2952 else if (!envval)
2953 {
2954 /* No argument - unset the environment variable */
2955 unsetenv(envvar);
2956 success = true;
2957 }
2958 else
2959 {
2960 /* Set variable to the value of the next argument */
2961 setenv(envvar, envval, 1);
2962 success = true;
2963 }
2964 free(envvar);
2965 free(envval);
2966 }
2967 else
2968 ignore_slash_options(scan_state);
2969
2971}
2972
2973/*
2974 * \sf/\sv -- show a function/view's source code
2975 */
2976static backslashResult
2977exec_command_sf_sv(PsqlScanState scan_state, bool active_branch,
2978 const char *cmd, bool is_func)
2979{
2981
2982 if (active_branch)
2983 {
2984 bool show_linenumbers = (strchr(cmd, '+') != NULL);
2986 char *obj_desc;
2987 Oid obj_oid = InvalidOid;
2989
2991 obj_desc = psql_scan_slash_option(scan_state,
2992 OT_WHOLE_LINE, NULL, true);
2993 if (!obj_desc)
2994 {
2995 if (is_func)
2996 pg_log_error("function name is required");
2997 else
2998 pg_log_error("view name is required");
2999 status = PSQL_CMD_ERROR;
3000 }
3001 else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
3002 {
3003 /* error already reported */
3004 status = PSQL_CMD_ERROR;
3005 }
3006 else if (!get_create_object_cmd(eot, obj_oid, buf))
3007 {
3008 /* error already reported */
3009 status = PSQL_CMD_ERROR;
3010 }
3011 else
3012 {
3013 FILE *output;
3014 bool is_pager;
3015
3016 /* Select output stream: stdout, pager, or file */
3017 if (pset.queryFout == stdout)
3018 {
3019 /* count lines in function to see if pager is needed */
3020 int lineno = count_lines_in_buf(buf);
3021
3022 output = PageOutput(lineno, &(pset.popt.topt));
3023 is_pager = true;
3024 }
3025 else
3026 {
3027 /* use previously set output file, without pager */
3029 is_pager = false;
3030 }
3031
3032 if (show_linenumbers)
3033 {
3034 /* add line numbers */
3035 print_with_linenumbers(output, buf->data, is_func);
3036 }
3037 else
3038 {
3039 /* just send the definition to output */
3040 fputs(buf->data, output);
3041 }
3042
3043 if (is_pager)
3045 }
3046
3047 free(obj_desc);
3049 }
3050 else
3051 ignore_slash_whole_line(scan_state);
3052
3053 return status;
3054}
3055
3056/*
3057 * \startpipeline -- enter pipeline mode
3058 */
3059static backslashResult
3060exec_command_startpipeline(PsqlScanState scan_state, bool active_branch)
3061{
3063
3064 if (active_branch)
3065 {
3067 status = PSQL_CMD_SEND;
3068 }
3069 else
3070 ignore_slash_options(scan_state);
3071
3072 return status;
3073}
3074
3075/*
3076 * \syncpipeline -- send a sync message to an active pipeline
3077 */
3078static backslashResult
3079exec_command_syncpipeline(PsqlScanState scan_state, bool active_branch)
3080{
3082
3083 if (active_branch)
3084 {
3086 status = PSQL_CMD_SEND;
3087 }
3088 else
3089 ignore_slash_options(scan_state);
3090
3091 return status;
3092}
3093
3094/*
3095 * \endpipeline -- end pipeline mode
3096 */
3097static backslashResult
3098exec_command_endpipeline(PsqlScanState scan_state, bool active_branch)
3099{
3101
3102 if (active_branch)
3103 {
3105 status = PSQL_CMD_SEND;
3106 }
3107 else
3108 ignore_slash_options(scan_state);
3109
3110 return status;
3111}
3112
3113/*
3114 * \t -- turn off table headers and row count
3115 */
3116static backslashResult
3117exec_command_t(PsqlScanState scan_state, bool active_branch)
3118{
3119 bool success = true;
3120
3121 if (active_branch)
3122 {
3123 char *opt = psql_scan_slash_option(scan_state,
3124 OT_NORMAL, NULL, true);
3125
3126 success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
3127 free(opt);
3128 }
3129 else
3130 ignore_slash_options(scan_state);
3131
3133}
3134
3135/*
3136 * \T -- define html <table ...> attributes
3137 */
3138static backslashResult
3139exec_command_T(PsqlScanState scan_state, bool active_branch)
3140{
3141 bool success = true;
3142
3143 if (active_branch)
3144 {
3145 char *value = psql_scan_slash_option(scan_state,
3146 OT_NORMAL, NULL, false);
3147
3148 success = do_pset("tableattr", value, &pset.popt, pset.quiet);
3149 free(value);
3150 }
3151 else
3152 ignore_slash_options(scan_state);
3153
3155}
3156
3157/*
3158 * \timing -- enable/disable timing of queries
3159 */
3160static backslashResult
3161exec_command_timing(PsqlScanState scan_state, bool active_branch)
3162{
3163 bool success = true;
3164
3165 if (active_branch)
3166 {
3167 char *opt = psql_scan_slash_option(scan_state,
3168 OT_NORMAL, NULL, false);
3169
3170 if (opt)
3171 success = ParseVariableBool(opt, "\\timing", &pset.timing);
3172 else
3174 if (!pset.quiet)
3175 {
3176 if (pset.timing)
3177 puts(_("Timing is on."));
3178 else
3179 puts(_("Timing is off."));
3180 }
3181 free(opt);
3182 }
3183 else
3184 ignore_slash_options(scan_state);
3185
3187}
3188
3189/*
3190 * \unrestrict -- exit "restricted mode" if provided key matches
3191 */
3192static backslashResult
3193exec_command_unrestrict(PsqlScanState scan_state, bool active_branch,
3194 const char *cmd)
3195{
3196 if (active_branch)
3197 {
3198 char *opt;
3199
3200 opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true);
3201 if (opt == NULL || opt[0] == '\0')
3202 {
3203 pg_log_error("\\%s: missing required argument", cmd);
3204 return PSQL_CMD_ERROR;
3205 }
3206
3207 if (!restricted)
3208 {
3209 pg_log_error("\\%s: not currently in restricted mode", cmd);
3210 return PSQL_CMD_ERROR;
3211 }
3212 else if (strcmp(opt, restrict_key) == 0)
3213 {
3215 restricted = false;
3216 }
3217 else
3218 {
3219 pg_log_error("\\%s: wrong key", cmd);
3220 return PSQL_CMD_ERROR;
3221 }
3222 }
3223 else
3224 ignore_slash_options(scan_state);
3225
3226 return PSQL_CMD_SKIP_LINE;
3227}
3228
3229/*
3230 * \unset -- unset variable
3231 */
3232static backslashResult
3233exec_command_unset(PsqlScanState scan_state, bool active_branch,
3234 const char *cmd)
3235{
3236 bool success = true;
3237
3238 if (active_branch)
3239 {
3240 char *opt = psql_scan_slash_option(scan_state,
3241 OT_NORMAL, NULL, false);
3242
3243 if (!opt)
3244 {
3245 pg_log_error("\\%s: missing required argument", cmd);
3246 success = false;
3247 }
3248 else if (!SetVariable(pset.vars, opt, NULL))
3249 success = false;
3250
3251 free(opt);
3252 }
3253 else
3254 ignore_slash_options(scan_state);
3255
3257}
3258
3259/*
3260 * \w -- write query buffer to file
3261 */
3262static backslashResult
3263exec_command_write(PsqlScanState scan_state, bool active_branch,
3264 const char *cmd,
3265 PQExpBuffer query_buf, PQExpBuffer previous_buf)
3266{
3268
3269 if (active_branch)
3270 {
3271 char *fname = psql_scan_slash_option(scan_state,
3272 OT_FILEPIPE, NULL, true);
3273 FILE *fd = NULL;
3274 bool is_pipe = false;
3275
3276 if (!query_buf)
3277 {
3278 pg_log_error("no query buffer");
3279 status = PSQL_CMD_ERROR;
3280 }
3281 else
3282 {
3283 if (!fname)
3284 {
3285 pg_log_error("\\%s: missing required argument", cmd);
3286 status = PSQL_CMD_ERROR;
3287 }
3288 else
3289 {
3290 expand_tilde(&fname);
3291 if (fname[0] == '|')
3292 {
3293 is_pipe = true;
3294 fflush(NULL);
3296 fd = popen(&fname[1], "w");
3297 }
3298 else
3299 {
3301 fd = fopen(fname, "w");
3302 }
3303 if (!fd)
3304 {
3305 pg_log_error("%s: %m", fname);
3306 status = PSQL_CMD_ERROR;
3307 }
3308 }
3309 }
3310
3311 if (fd)
3312 {
3313 int result;
3314
3315 /*
3316 * We want to print the same thing \g would execute, but not to
3317 * change the query buffer state; so we can't use
3318 * copy_previous_query(). Also, beware of possibility that buffer
3319 * pointers are NULL.
3320 */
3321 if (query_buf && query_buf->len > 0)
3322 fprintf(fd, "%s\n", query_buf->data);
3323 else if (previous_buf && previous_buf->len > 0)
3324 fprintf(fd, "%s\n", previous_buf->data);
3325
3326 if (is_pipe)
3327 {
3328 result = pclose(fd);
3329
3330 if (result != 0)
3331 {
3332 pg_log_error("%s: %s", fname, wait_result_to_str(result));
3333 status = PSQL_CMD_ERROR;
3334 }
3336 }
3337 else
3338 {
3339 result = fclose(fd);
3340
3341 if (result == EOF)
3342 {
3343 pg_log_error("%s: %m", fname);
3344 status = PSQL_CMD_ERROR;
3345 }
3346 }
3347 }
3348
3349 if (is_pipe)
3351
3352 free(fname);
3353 }
3354 else
3355 ignore_slash_filepipe(scan_state);
3356
3357 return status;
3358}
3359
3360/*
3361 * \watch -- execute a query every N seconds.
3362 * Optionally, stop after M iterations.
3363 */
3364static backslashResult
3365exec_command_watch(PsqlScanState scan_state, bool active_branch,
3366 PQExpBuffer query_buf, PQExpBuffer previous_buf)
3367{
3368 bool success = true;
3369
3370 if (active_branch)
3371 {
3372 bool have_sleep = false;
3373 bool have_iter = false;
3374 bool have_min_rows = false;
3375 double sleep = pset.watch_interval;
3376 int iter = 0;
3377 int min_rows = 0;
3378
3380 {
3381 pg_log_error("\\%s not allowed in pipeline mode", "watch");
3383 success = false;
3384 }
3385
3386 /*
3387 * Parse arguments. We allow either an unlabeled interval or
3388 * "name=value", where name is from the set ('i', 'interval', 'c',
3389 * 'count', 'm', 'min_rows'). The parsing of interval value should be
3390 * kept in sync with ParseVariableDouble which is used for setting the
3391 * default interval value.
3392 */
3393 while (success)
3394 {
3395 char *opt = psql_scan_slash_option(scan_state,
3396 OT_NORMAL, NULL, true);
3397 char *valptr;
3398 char *opt_end;
3399
3400 if (!opt)
3401 break; /* no more arguments */
3402
3403 valptr = strchr(opt, '=');
3404 if (valptr)
3405 {
3406 /* Labeled argument */
3407 valptr++;
3408 if (strncmp("i=", opt, strlen("i=")) == 0 ||
3409 strncmp("interval=", opt, strlen("interval=")) == 0)
3410 {
3411 if (have_sleep)
3412 {
3413 pg_log_error("\\watch: interval value is specified more than once");
3414 success = false;
3415 }
3416 else
3417 {
3418 have_sleep = true;
3419 errno = 0;
3420 sleep = strtod(valptr, &opt_end);
3421 if (sleep < 0 || *opt_end || errno == ERANGE)
3422 {
3423 pg_log_error("\\watch: incorrect interval value \"%s\"", valptr);
3424 success = false;
3425 }
3426 }
3427 }
3428 else if (strncmp("c=", opt, strlen("c=")) == 0 ||
3429 strncmp("count=", opt, strlen("count=")) == 0)
3430 {
3431 if (have_iter)
3432 {
3433 pg_log_error("\\watch: iteration count is specified more than once");
3434 success = false;
3435 }
3436 else
3437 {
3438 have_iter = true;
3439 errno = 0;
3440 iter = strtoint(valptr, &opt_end, 10);
3441 if (iter <= 0 || *opt_end || errno == ERANGE)
3442 {
3443 pg_log_error("\\watch: incorrect iteration count \"%s\"", valptr);
3444 success = false;
3445 }
3446 }
3447 }
3448 else if (strncmp("m=", opt, strlen("m=")) == 0 ||
3449 strncmp("min_rows=", opt, strlen("min_rows=")) == 0)
3450 {
3451 if (have_min_rows)
3452 {
3453 pg_log_error("\\watch: minimum row count specified more than once");
3454 success = false;
3455 }
3456 else
3457 {
3458 have_min_rows = true;
3459 errno = 0;
3460 min_rows = strtoint(valptr, &opt_end, 10);
3461 if (min_rows <= 0 || *opt_end || errno == ERANGE)
3462 {
3463 pg_log_error("\\watch: incorrect minimum row count \"%s\"", valptr);
3464 success = false;
3465 }
3466 }
3467 }
3468 else
3469 {
3470 pg_log_error("\\watch: unrecognized parameter \"%s\"", opt);
3471 success = false;
3472 }
3473 }
3474 else
3475 {
3476 /* Unlabeled argument: take it as interval */
3477 if (have_sleep)
3478 {
3479 pg_log_error("\\watch: interval value is specified more than once");
3480 success = false;
3481 }
3482 else
3483 {
3484 have_sleep = true;
3485 errno = 0;
3486 sleep = strtod(opt, &opt_end);
3487 if (sleep < 0 || *opt_end || errno == ERANGE)
3488 {
3489 pg_log_error("\\watch: incorrect interval value \"%s\"", opt);
3490 success = false;
3491 }
3492 }
3493 }
3494
3495 free(opt);
3496 }
3497
3498 /* If we parsed arguments successfully, do the command */
3499 if (success)
3500 {
3501 /* If query_buf is empty, recall and execute previous query */
3502 (void) copy_previous_query(query_buf, previous_buf);
3503
3504 success = do_watch(query_buf, sleep, iter, min_rows);
3505 }
3506
3507 /* Reset the query buffer as though for \r */
3508 resetPQExpBuffer(query_buf);
3509 psql_scan_reset(scan_state);
3510 }
3511 else
3512 ignore_slash_options(scan_state);
3513
3515}
3516
3517/*
3518 * \x -- set or toggle expanded table representation
3519 */
3520static backslashResult
3521exec_command_x(PsqlScanState scan_state, bool active_branch)
3522{
3523 bool success = true;
3524
3525 if (active_branch)
3526 {
3527 char *opt = psql_scan_slash_option(scan_state,
3528 OT_NORMAL, NULL, true);
3529
3530 success = do_pset("expanded", opt, &pset.popt, pset.quiet);
3531 free(opt);
3532 }
3533 else
3534 ignore_slash_options(scan_state);
3535
3537}
3538
3539/*
3540 * \z -- list table privileges (equivalent to \dp)
3541 */
3542static backslashResult
3543exec_command_z(PsqlScanState scan_state, bool active_branch, const char *cmd)
3544{
3545 bool success = true;
3546
3547 if (active_branch)
3548 {
3549 char *pattern;
3550 bool show_system;
3551 unsigned short int save_expanded;
3552
3553 pattern = psql_scan_slash_option(scan_state,
3554 OT_NORMAL, NULL, true);
3555
3556 show_system = strchr(cmd, 'S') ? true : false;
3557
3558 /* if 'x' option specified, force expanded mode */
3559 save_expanded = pset.popt.topt.expanded;
3560 if (strchr(cmd, 'x'))
3561 pset.popt.topt.expanded = 1;
3562
3563 success = permissionsList(pattern, show_system);
3564
3565 /* restore original expanded mode */
3566 pset.popt.topt.expanded = save_expanded;
3567
3568 free(pattern);
3569 }
3570 else
3571 ignore_slash_options(scan_state);
3572
3574}
3575
3576/*
3577 * \! -- execute shell command
3578 */
3579static backslashResult
3580exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
3581{
3582 bool success = true;
3583
3584 if (active_branch)
3585 {
3586 char *opt = psql_scan_slash_option(scan_state,
3587 OT_WHOLE_LINE, NULL, false);
3588
3589 success = do_shell(opt);
3590 free(opt);
3591 }
3592 else
3593 ignore_slash_whole_line(scan_state);
3594
3596}
3597
3598/*
3599 * \? -- print help about backslash commands
3600 */
3601static backslashResult
3602exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
3603{
3604 if (active_branch)
3605 {
3606 char *opt0 = psql_scan_slash_option(scan_state,
3607 OT_NORMAL, NULL, false);
3608
3609 if (!opt0 || strcmp(opt0, "commands") == 0)
3611 else if (strcmp(opt0, "options") == 0)
3613 else if (strcmp(opt0, "variables") == 0)
3615 else
3617
3618 free(opt0);
3619 }
3620 else
3621 ignore_slash_options(scan_state);
3622
3623 return PSQL_CMD_SKIP_LINE;
3624}
3625
3626
3627/*
3628 * Read and interpret an argument to the \connect slash command.
3629 *
3630 * Returns a malloc'd string, or NULL if no/empty argument.
3631 */
3632static char *
3634{
3635 char *result;
3636 char quote;
3637
3638 /*
3639 * Ideally we should treat the arguments as SQL identifiers. But for
3640 * backwards compatibility with 7.2 and older pg_dump files, we have to
3641 * take unquoted arguments verbatim (don't downcase them). For now,
3642 * double-quoted arguments may be stripped of double quotes (as if SQL
3643 * identifiers). By 7.4 or so, pg_dump files can be expected to
3644 * double-quote all mixed-case \connect arguments, and then we can get rid
3645 * of OT_SQLIDHACK.
3646 */
3647 result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, &quote, true);
3648
3649 if (!result)
3650 return NULL;
3651
3652 if (quote)
3653 return result;
3654
3655 if (*result == '\0' || strcmp(result, "-") == 0)
3656 {
3657 free(result);
3658 return NULL;
3659 }
3660
3661 return result;
3662}
3663
3664/*
3665 * Read a boolean expression, return it as a PQExpBuffer string.
3666 *
3667 * Note: anything more or less than one token will certainly fail to be
3668 * parsed by ParseVariableBool, so we don't worry about complaining here.
3669 * This routine's return data structure will need to be rethought anyway
3670 * to support likely future extensions such as "\if defined VARNAME".
3671 */
3672static PQExpBuffer
3674{
3675 PQExpBuffer exp_buf = createPQExpBuffer();
3676 int num_options = 0;
3677 char *value;
3678
3679 /* collect all arguments for the conditional command into exp_buf */
3680 while ((value = psql_scan_slash_option(scan_state,
3681 OT_NORMAL, NULL, false)) != NULL)
3682 {
3683 /* add spaces between tokens */
3684 if (num_options > 0)
3685 appendPQExpBufferChar(exp_buf, ' ');
3686 appendPQExpBufferStr(exp_buf, value);
3687 num_options++;
3688 free(value);
3689 }
3690
3691 return exp_buf;
3692}
3693
3694/*
3695 * Read a boolean expression, return true if the expression
3696 * was a valid boolean expression that evaluated to true.
3697 * Otherwise return false.
3698 *
3699 * Note: conditional stack's top state must be active, else lexer will
3700 * fail to expand variables and backticks.
3701 */
3702static bool
3704{
3706 bool value = false;
3707 bool success = ParseVariableBool(buf->data, name, &value);
3708
3710 return success && value;
3711}
3712
3713/*
3714 * Read a boolean expression, but do nothing with it.
3715 *
3716 * Note: conditional stack's top state must be INACTIVE, else lexer will
3717 * expand variables and backticks, which we do not want here.
3718 */
3719static void
3721{
3723
3725}
3726
3727/*
3728 * Read and discard "normal" slash command options.
3729 *
3730 * This should be used for inactive-branch processing of any slash command
3731 * that eats one or more OT_NORMAL, OT_SQLID, or OT_SQLIDHACK parameters.
3732 * We don't need to worry about exactly how many it would eat, since the
3733 * cleanup logic in HandleSlashCmds would silently discard any extras anyway.
3734 */
3735static void
3737{
3738 char *arg;
3739
3740 while ((arg = psql_scan_slash_option(scan_state,
3741 OT_NORMAL, NULL, false)) != NULL)
3742 free(arg);
3743}
3744
3745/*
3746 * Read and discard FILEPIPE slash command argument.
3747 *
3748 * This *MUST* be used for inactive-branch processing of any slash command
3749 * that takes an OT_FILEPIPE option. Otherwise we might consume a different
3750 * amount of option text in active and inactive cases.
3751 */
3752static void
3754{
3755 char *arg = psql_scan_slash_option(scan_state,
3756 OT_FILEPIPE, NULL, false);
3757
3758 free(arg);
3759}
3760
3761/*
3762 * Read and discard whole-line slash command argument.
3763 *
3764 * This *MUST* be used for inactive-branch processing of any slash command
3765 * that takes an OT_WHOLE_LINE option. Otherwise we might consume a different
3766 * amount of option text in active and inactive cases.
3767 *
3768 * Note: although callers might pass "semicolon" as either true or false,
3769 * we need not duplicate that here, since it doesn't affect the amount of
3770 * input text consumed.
3771 */
3772static void
3774{
3775 char *arg = psql_scan_slash_option(scan_state,
3776 OT_WHOLE_LINE, NULL, false);
3777
3778 free(arg);
3779}
3780
3781/*
3782 * Return true if the command given is a branching command.
3783 */
3784static bool
3785is_branching_command(const char *cmd)
3786{
3787 return (strcmp(cmd, "if") == 0 ||
3788 strcmp(cmd, "elif") == 0 ||
3789 strcmp(cmd, "else") == 0 ||
3790 strcmp(cmd, "endif") == 0);
3791}
3792
3793/*
3794 * Prepare to possibly restore query buffer to its current state
3795 * (cf. discard_query_text).
3796 *
3797 * We need to remember the length of the query buffer, and the lexer's
3798 * notion of the parenthesis nesting depth.
3799 */
3800static void
3802 PQExpBuffer query_buf)
3803{
3804 if (query_buf)
3805 conditional_stack_set_query_len(cstack, query_buf->len);
3807 psql_scan_get_paren_depth(scan_state));
3808}
3809
3810/*
3811 * Discard any query text absorbed during an inactive conditional branch.
3812 *
3813 * We must discard data that was appended to query_buf during an inactive
3814 * \if branch. We don't have to do anything there if there's no query_buf.
3815 *
3816 * Also, reset the lexer state to the same paren depth there was before.
3817 * (The rest of its state doesn't need attention, since we could not be
3818 * inside a comment or literal or partial token.)
3819 */
3820static void
3822 PQExpBuffer query_buf)
3823{
3824 if (query_buf)
3825 {
3826 int new_len = conditional_stack_get_query_len(cstack);
3827
3828 Assert(new_len >= 0 && new_len <= query_buf->len);
3829 query_buf->len = new_len;
3830 query_buf->data[new_len] = '\0';
3831 }
3832 psql_scan_set_paren_depth(scan_state,
3834}
3835
3836/*
3837 * If query_buf is empty, copy previous_buf into it.
3838 *
3839 * This is used by various slash commands for which re-execution of a
3840 * previous query is a common usage. For convenience, we allow the
3841 * case of query_buf == NULL (and do nothing).
3842 *
3843 * Returns "true" if the previous query was copied into the query
3844 * buffer, else "false".
3845 */
3846static bool
3848{
3849 if (query_buf && query_buf->len == 0)
3850 {
3851 appendPQExpBufferStr(query_buf, previous_buf->data);
3852 return true;
3853 }
3854 return false;
3855}
3856
3857/*
3858 * Ask the user for a password; 'username' is the username the
3859 * password is for, if one has been explicitly specified.
3860 * Returns a malloc'd string.
3861 * If 'canceled' is provided, *canceled will be set to true if the prompt
3862 * is canceled via SIGINT, and to false otherwise.
3863 */
3864static char *
3865prompt_for_password(const char *username, bool *canceled)
3866{
3867 char *result;
3868 PromptInterruptContext prompt_ctx;
3869
3870 /* Set up to let SIGINT cancel simple_prompt_extended() */
3871 prompt_ctx.jmpbuf = sigint_interrupt_jmp;
3872 prompt_ctx.enabled = &sigint_interrupt_enabled;
3873 prompt_ctx.canceled = false;
3874
3875 if (username == NULL || username[0] == '\0')
3876 result = simple_prompt_extended("Password: ", false, &prompt_ctx);
3877 else
3878 {
3879 char *prompt_text;
3880
3881 prompt_text = psprintf(_("Password for user %s: "), username);
3882 result = simple_prompt_extended(prompt_text, false, &prompt_ctx);
3883 free(prompt_text);
3884 }
3885
3886 if (canceled)
3887 *canceled = prompt_ctx.canceled;
3888
3889 return result;
3890}
3891
3892static bool
3893param_is_newly_set(const char *old_val, const char *new_val)
3894{
3895 if (new_val == NULL)
3896 return false;
3897
3898 if (old_val == NULL || strcmp(old_val, new_val) != 0)
3899 return true;
3900
3901 return false;
3902}
3903
3904/*
3905 * do_connect -- handler for \connect
3906 *
3907 * Connects to a database with given parameters. If we are told to re-use
3908 * parameters, parameters from the previous connection are used where the
3909 * command's own options do not supply a value. Otherwise, libpq defaults
3910 * are used.
3911 *
3912 * In interactive mode, if connection fails with the given parameters,
3913 * the old connection will be kept.
3914 */
3915static bool
3916do_connect(enum trivalue reuse_previous_specification,
3917 char *dbname, char *user, char *host, char *port)
3918{
3919 PGconn *o_conn = pset.db,
3920 *n_conn = NULL;
3921 PQconninfoOption *cinfo;
3922 int nconnopts = 0;
3923 bool same_host = false;
3924 char *password = NULL;
3925 char *client_encoding;
3926 bool success = true;
3927 bool keep_password = true;
3928 bool has_connection_string;
3929 bool reuse_previous;
3930
3931 has_connection_string = dbname ?
3933
3934 /* Complain if we have additional arguments after a connection string. */
3935 if (has_connection_string && (user || host || port))
3936 {
3937 pg_log_error("Do not give user, host, or port separately when using a connection string");
3938 return false;
3939 }
3940
3941 switch (reuse_previous_specification)
3942 {
3943 case TRI_YES:
3944 reuse_previous = true;
3945 break;
3946 case TRI_NO:
3947 reuse_previous = false;
3948 break;
3949 default:
3950 reuse_previous = !has_connection_string;
3951 break;
3952 }
3953
3954 /*
3955 * If we intend to re-use connection parameters, collect them out of the
3956 * old connection, then replace individual values as necessary. (We may
3957 * need to resort to looking at pset.dead_conn, if the connection died
3958 * previously.) Otherwise, obtain a PQconninfoOption array containing
3959 * libpq's defaults, and modify that. Note this function assumes that
3960 * PQconninfo, PQconndefaults, and PQconninfoParse will all produce arrays
3961 * containing the same options in the same order.
3962 */
3963 if (reuse_previous)
3964 {
3965 if (o_conn)
3966 cinfo = PQconninfo(o_conn);
3967 else if (pset.dead_conn)
3968 cinfo = PQconninfo(pset.dead_conn);
3969 else
3970 {
3971 /* This is reachable after a non-interactive \connect failure */
3972 pg_log_error("No database connection exists to re-use parameters from");
3973 return false;
3974 }
3975 }
3976 else
3977 cinfo = PQconndefaults();
3978
3979 if (cinfo)
3980 {
3981 if (has_connection_string)
3982 {
3983 /* Parse the connstring and insert values into cinfo */
3984 PQconninfoOption *replcinfo;
3985 char *errmsg;
3986
3987 replcinfo = PQconninfoParse(dbname, &errmsg);
3988 if (replcinfo)
3989 {
3990 PQconninfoOption *ci;
3991 PQconninfoOption *replci;
3992 bool have_password = false;
3993
3994 for (ci = cinfo, replci = replcinfo;
3995 ci->keyword && replci->keyword;
3996 ci++, replci++)
3997 {
3998 Assert(strcmp(ci->keyword, replci->keyword) == 0);
3999 /* Insert value from connstring if one was provided */
4000 if (replci->val)
4001 {
4002 /*
4003 * We know that both val strings were allocated by
4004 * libpq, so the least messy way to avoid memory leaks
4005 * is to swap them.
4006 */
4007 char *swap = replci->val;
4008
4009 replci->val = ci->val;
4010 ci->val = swap;
4011
4012 /*
4013 * Check whether connstring provides options affecting
4014 * password re-use. While any change in user, host,
4015 * hostaddr, or port causes us to ignore the old
4016 * connection's password, we don't force that for
4017 * dbname, since passwords aren't database-specific.
4018 */
4019 if (replci->val == NULL ||
4020 strcmp(ci->val, replci->val) != 0)
4021 {
4022 if (strcmp(replci->keyword, "user") == 0 ||
4023 strcmp(replci->keyword, "host") == 0 ||
4024 strcmp(replci->keyword, "hostaddr") == 0 ||
4025 strcmp(replci->keyword, "port") == 0)
4026 keep_password = false;
4027 }
4028 /* Also note whether connstring contains a password. */
4029 if (strcmp(replci->keyword, "password") == 0)
4030 have_password = true;
4031 }
4032 else if (!reuse_previous)
4033 {
4034 /*
4035 * When we have a connstring and are not re-using
4036 * parameters, swap *all* entries, even those not set
4037 * by the connstring. This avoids absorbing
4038 * environment-dependent defaults from the result of
4039 * PQconndefaults(). We don't want to do that because
4040 * they'd override service-file entries if the
4041 * connstring specifies a service parameter, whereas
4042 * the priority should be the other way around. libpq
4043 * can certainly recompute any defaults we don't pass
4044 * here. (In this situation, it's a bit wasteful to
4045 * have called PQconndefaults() at all, but not doing
4046 * so would require yet another major code path here.)
4047 */
4048 replci->val = ci->val;
4049 ci->val = NULL;
4050 }
4051 }
4052 Assert(ci->keyword == NULL && replci->keyword == NULL);
4053
4054 /* While here, determine how many option slots there are */
4055 nconnopts = ci - cinfo;
4056
4057 PQconninfoFree(replcinfo);
4058
4059 /*
4060 * If the connstring contains a password, tell the loop below
4061 * that we may use it, regardless of other settings (i.e.,
4062 * cinfo's password is no longer an "old" password).
4063 */
4064 if (have_password)
4065 keep_password = true;
4066
4067 /* Don't let code below try to inject dbname into params. */
4068 dbname = NULL;
4069 }
4070 else
4071 {
4072 /* PQconninfoParse failed */
4073 if (errmsg)
4074 {
4075 pg_log_error("%s", errmsg);
4077 }
4078 else
4079 pg_log_error("out of memory");
4080 success = false;
4081 }
4082 }
4083 else
4084 {
4085 /*
4086 * If dbname isn't a connection string, then we'll inject it and
4087 * the other parameters into the keyword array below. (We can't
4088 * easily insert them into the cinfo array because of memory
4089 * management issues: PQconninfoFree would misbehave on Windows.)
4090 * However, to avoid dependencies on the order in which parameters
4091 * appear in the array, make a preliminary scan to set
4092 * keep_password and same_host correctly.
4093 *
4094 * While any change in user, host, or port causes us to ignore the
4095 * old connection's password, we don't force that for dbname,
4096 * since passwords aren't database-specific.
4097 */
4098 PQconninfoOption *ci;
4099
4100 for (ci = cinfo; ci->keyword; ci++)
4101 {
4102 if (user && strcmp(ci->keyword, "user") == 0)
4103 {
4104 if (!(ci->val && strcmp(user, ci->val) == 0))
4105 keep_password = false;
4106 }
4107 else if (host && strcmp(ci->keyword, "host") == 0)
4108 {
4109 if (ci->val && strcmp(host, ci->val) == 0)
4110 same_host = true;
4111 else
4112 keep_password = false;
4113 }
4114 else if (port && strcmp(ci->keyword, "port") == 0)
4115 {
4116 if (!(ci->val && strcmp(port, ci->val) == 0))
4117 keep_password = false;
4118 }
4119 }
4120
4121 /* While here, determine how many option slots there are */
4122 nconnopts = ci - cinfo;
4123 }
4124 }
4125 else
4126 {
4127 /* We failed to create the cinfo structure */
4128 pg_log_error("out of memory");
4129 success = false;
4130 }
4131
4132 /*
4133 * If the user asked to be prompted for a password, ask for one now. If
4134 * not, use the password from the old connection, provided the username
4135 * etc have not changed. Otherwise, try to connect without a password
4136 * first, and then ask for a password if needed.
4137 *
4138 * XXX: this behavior leads to spurious connection attempts recorded in
4139 * the postmaster's log. But libpq offers no API that would let us obtain
4140 * a password and then continue with the first connection attempt.
4141 */
4142 if (pset.getPassword == TRI_YES && success)
4143 {
4144 bool canceled = false;
4145
4146 /*
4147 * If a connstring or URI is provided, we don't know which username
4148 * will be used, since we haven't dug that out of the connstring.
4149 * Don't risk issuing a misleading prompt. As in startup.c, it does
4150 * not seem worth working harder, since this getPassword setting is
4151 * normally only used in noninteractive cases.
4152 */
4153 password = prompt_for_password(has_connection_string ? NULL : user,
4154 &canceled);
4155 success = !canceled;
4156 }
4157
4158 /*
4159 * Consider whether to force client_encoding to "auto" (overriding
4160 * anything in the connection string). We do so if we have a terminal
4161 * connection and there is no PGCLIENTENCODING environment setting.
4162 */
4163 if (pset.notty || getenv("PGCLIENTENCODING"))
4164 client_encoding = NULL;
4165 else
4166 client_encoding = "auto";
4167
4168 /* Loop till we have a connection or fail, which we might've already */
4169 while (success)
4170 {
4171 const char **keywords = pg_malloc((nconnopts + 1) * sizeof(*keywords));
4172 const char **values = pg_malloc((nconnopts + 1) * sizeof(*values));
4173 int paramnum = 0;
4174 PQconninfoOption *ci;
4175
4176 /*
4177 * Copy non-default settings into the PQconnectdbParams parameter
4178 * arrays; but inject any values specified old-style, as well as any
4179 * interactively-obtained password, and a couple of fields we want to
4180 * set forcibly.
4181 *
4182 * If you change this code, see also the initial-connection code in
4183 * main().
4184 */
4185 for (ci = cinfo; ci->keyword; ci++)
4186 {
4187 keywords[paramnum] = ci->keyword;
4188
4189 if (dbname && strcmp(ci->keyword, "dbname") == 0)
4190 values[paramnum++] = dbname;
4191 else if (user && strcmp(ci->keyword, "user") == 0)
4192 values[paramnum++] = user;
4193 else if (host && strcmp(ci->keyword, "host") == 0)
4194 values[paramnum++] = host;
4195 else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0)
4196 {
4197 /* If we're changing the host value, drop any old hostaddr */
4198 values[paramnum++] = NULL;
4199 }
4200 else if (port && strcmp(ci->keyword, "port") == 0)
4201 values[paramnum++] = port;
4202 /* If !keep_password, we unconditionally drop old password */
4203 else if ((password || !keep_password) &&
4204 strcmp(ci->keyword, "password") == 0)
4205 values[paramnum++] = password;
4206 else if (strcmp(ci->keyword, "fallback_application_name") == 0)
4207 values[paramnum++] = pset.progname;
4208 else if (client_encoding &&
4209 strcmp(ci->keyword, "client_encoding") == 0)
4210 values[paramnum++] = client_encoding;
4211 else if (ci->val)
4212 values[paramnum++] = ci->val;
4213 /* else, don't bother making libpq parse this keyword */
4214 }
4215 /* add array terminator */
4216 keywords[paramnum] = NULL;
4217 values[paramnum] = NULL;
4218
4219 /* Note we do not want libpq to re-expand the dbname parameter */
4220 n_conn = PQconnectStartParams(keywords, values, false);
4221
4223 pg_free(values);
4224
4225 wait_until_connected(n_conn);
4226 if (PQstatus(n_conn) == CONNECTION_OK)
4227 break;
4228
4229 /*
4230 * Connection attempt failed; either retry the connection attempt with
4231 * a new password, or give up.
4232 */
4234 {
4235 bool canceled = false;
4236
4237 /*
4238 * Prompt for password using the username we actually connected
4239 * with --- it might've come out of "dbname" rather than "user".
4240 */
4241 password = prompt_for_password(PQuser(n_conn), &canceled);
4242 PQfinish(n_conn);
4243 n_conn = NULL;
4244 success = !canceled;
4245 continue;
4246 }
4247
4248 /*
4249 * We'll report the error below ... unless n_conn is NULL, indicating
4250 * that libpq didn't have enough memory to make a PGconn.
4251 */
4252 if (n_conn == NULL)
4253 pg_log_error("out of memory");
4254
4255 success = false;
4256 } /* end retry loop */
4257
4258 /* Release locally allocated data, whether we succeeded or not */
4260 PQconninfoFree(cinfo);
4261
4262 if (!success)
4263 {
4264 /*
4265 * Failed to connect to the database. In interactive mode, keep the
4266 * previous connection to the DB; in scripting mode, close our
4267 * previous connection as well.
4268 */
4270 {
4271 if (n_conn)
4272 {
4273 pg_log_info("%s", PQerrorMessage(n_conn));
4274 PQfinish(n_conn);
4275 }
4276
4277 /* pset.db is left unmodified */
4278 if (o_conn)
4279 pg_log_info("Previous connection kept");
4280 }
4281 else
4282 {
4283 if (n_conn)
4284 {
4285 pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
4286 PQfinish(n_conn);
4287 }
4288
4289 if (o_conn)
4290 {
4291 /*
4292 * Transition to having no connection.
4293 *
4294 * Unlike CheckConnection(), we close the old connection
4295 * immediately to prevent its parameters from being re-used.
4296 * This is so that a script cannot accidentally reuse
4297 * parameters it did not expect to. Otherwise, the state
4298 * cleanup should be the same as in CheckConnection().
4299 */
4300 PQfinish(o_conn);
4301 pset.db = NULL;
4304 }
4305
4306 /* On the same reasoning, release any dead_conn to prevent reuse */
4307 if (pset.dead_conn)
4308 {
4310 pset.dead_conn = NULL;
4311 }
4312 }
4313
4314 return false;
4315 }
4316
4317 /*
4318 * Replace the old connection with the new one, and update
4319 * connection-dependent variables. Keep the resynchronization logic in
4320 * sync with CheckConnection().
4321 */
4323 pset.db = n_conn;
4324 SyncVariables();
4325 connection_warnings(false); /* Must be after SyncVariables */
4326
4327 /* Tell the user about the new connection */
4328 if (!pset.quiet)
4329 {
4330 if (!o_conn ||
4331 param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
4333 {
4334 char *connhost = PQhost(pset.db);
4335 char *hostaddr = PQhostaddr(pset.db);
4336
4337 if (is_unixsock_path(connhost))
4338 {
4339 /* hostaddr overrides connhost */
4340 if (hostaddr && *hostaddr)
4341 printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
4342 PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
4343 else
4344 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
4345 PQdb(pset.db), PQuser(pset.db), connhost, PQport(pset.db));
4346 }
4347 else
4348 {
4349 if (hostaddr && *hostaddr && strcmp(connhost, hostaddr) != 0)
4350 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
4351 PQdb(pset.db), PQuser(pset.db), connhost, hostaddr, PQport(pset.db));
4352 else
4353 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
4354 PQdb(pset.db), PQuser(pset.db), connhost, PQport(pset.db));
4355 }
4356 }
4357 else
4358 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
4359 PQdb(pset.db), PQuser(pset.db));
4360 }
4361
4362 /* Drop no-longer-needed connection(s) */
4363 if (o_conn)
4364 PQfinish(o_conn);
4365 if (pset.dead_conn)
4366 {
4368 pset.dead_conn = NULL;
4369 }
4370
4371 return true;
4372}
4373
4374/*
4375 * Processes the connection sequence described by PQconnectStartParams(). Don't
4376 * worry about reporting errors in this function. Our caller will check the
4377 * connection's status, and report appropriately.
4378 */
4379static void
4381{
4382 bool forRead = false;
4383
4384 while (true)
4385 {
4386 int rc;
4387 int sock;
4389
4390 /*
4391 * On every iteration of the connection sequence, let's check if the
4392 * user has requested a cancellation.
4393 */
4394 if (cancel_pressed)
4395 break;
4396
4397 /*
4398 * Do not assume that the socket remains the same across
4399 * PQconnectPoll() calls.
4400 */
4401 sock = PQsocket(conn);
4402 if (sock == -1)
4403 break;
4404
4405 /*
4406 * If the user sends SIGINT between the cancel_pressed check, and
4407 * polling of the socket, it will not be recognized. Instead, we will
4408 * just wait until the next step in the connection sequence or
4409 * forever, which might require users to send SIGTERM or SIGQUIT.
4410 *
4411 * Some solutions would include the "self-pipe trick," using
4412 * pselect(2) and ppoll(2), or using a timeout.
4413 *
4414 * The self-pipe trick requires a bit of code to setup. pselect(2) and
4415 * ppoll(2) are not on all the platforms we support. The simplest
4416 * solution happens to just be adding a timeout, so let's wait for 1
4417 * second and check cancel_pressed again.
4418 */
4419 end_time = PQgetCurrentTimeUSec() + 1000000;
4420 rc = PQsocketPoll(sock, forRead, !forRead, end_time);
4421 if (rc == -1)
4422 return;
4423
4424 switch (PQconnectPoll(conn))
4425 {
4426 case PGRES_POLLING_OK:
4428 return;
4430 forRead = true;
4431 continue;
4433 forRead = false;
4434 continue;
4437 }
4438 }
4439}
4440
4441void
4442connection_warnings(bool in_startup)
4443{
4444 if (!pset.quiet && !pset.notty)
4445 {
4446 int client_ver = PG_VERSION_NUM;
4447 char cverbuf[32];
4448 char sverbuf[32];
4449
4450 if (pset.sversion != client_ver)
4451 {
4452 const char *server_version;
4453
4454 /* Try to get full text form, might include "devel" etc */
4455 server_version = PQparameterStatus(pset.db, "server_version");
4456 /* Otherwise fall back on pset.sversion */
4457 if (!server_version)
4458 {
4460 sverbuf, sizeof(sverbuf));
4461 server_version = sverbuf;
4462 }
4463
4464 printf(_("%s (%s, server %s)\n"),
4465 pset.progname, PG_VERSION, server_version);
4466 }
4467 /* For version match, only print psql banner on startup. */
4468 else if (in_startup)
4469 printf("%s (%s)\n", pset.progname, PG_VERSION);
4470
4471 /*
4472 * Warn if server's major version is newer than ours, or if server
4473 * predates our support cutoff (currently 9.2).
4474 */
4475 if (pset.sversion / 100 > client_ver / 100 ||
4476 pset.sversion < 90200)
4477 printf(_("WARNING: %s major version %s, server major version %s.\n"
4478 " Some psql features might not work.\n"),
4479 pset.progname,
4480 formatPGVersionNumber(client_ver, false,
4481 cverbuf, sizeof(cverbuf)),
4483 sverbuf, sizeof(sverbuf)));
4484
4485#ifdef WIN32
4486 if (in_startup)
4487 checkWin32Codepage();
4488#endif
4489 printSSLInfo();
4490 printGSSInfo();
4491 }
4492}
4493
4494
4495/*
4496 * printSSLInfo
4497 *
4498 * Prints information about the current SSL connection, if SSL is in use
4499 */
4500static void
4502{
4503 const char *protocol;
4504 const char *cipher;
4505 const char *compression;
4506 const char *alpn;
4507
4508 if (!PQsslInUse(pset.db))
4509 return; /* no SSL */
4510
4511 protocol = PQsslAttribute(pset.db, "protocol");
4512 cipher = PQsslAttribute(pset.db, "cipher");
4513 compression = PQsslAttribute(pset.db, "compression");
4514 alpn = PQsslAttribute(pset.db, "alpn");
4515
4516 printf(_("SSL connection (protocol: %s, cipher: %s, compression: %s, ALPN: %s)\n"),
4517 protocol ? protocol : _("unknown"),
4518 cipher ? cipher : _("unknown"),
4519 (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"),
4520 (alpn && alpn[0] != '\0') ? alpn : _("none"));
4521}
4522
4523/*
4524 * printGSSInfo
4525 *
4526 * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use
4527 */
4528static void
4530{
4531 if (!PQgssEncInUse(pset.db))
4532 return; /* no GSSAPI encryption in use */
4533
4534 printf(_("GSSAPI-encrypted connection\n"));
4535}
4536
4537
4538/*
4539 * checkWin32Codepage
4540 *
4541 * Prints a warning when win32 console codepage differs from Windows codepage
4542 */
4543#ifdef WIN32
4544static void
4545checkWin32Codepage(void)
4546{
4547 unsigned int wincp,
4548 concp;
4549
4550 wincp = GetACP();
4551 concp = GetConsoleCP();
4552 if (wincp != concp)
4553 {
4554 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
4555 " 8-bit characters might not work correctly. See psql reference\n"
4556 " page \"Notes for Windows users\" for details.\n"),
4557 concp, wincp);
4558 }
4559}
4560#endif
4561
4562
4563/*
4564 * SyncVariables
4565 *
4566 * Make psql's internal variables agree with connection state upon
4567 * establishing a new connection.
4568 */
4569void
4571{
4572 char vbuf[32];
4573 const char *server_version;
4574 char *service_name;
4575 char *service_file;
4576
4577 /* get stuff from connection */
4581
4583
4584 SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
4585 SetVariable(pset.vars, "USER", PQuser(pset.db));
4586 SetVariable(pset.vars, "HOST", PQhost(pset.db));
4587 SetVariable(pset.vars, "PORT", PQport(pset.db));
4589
4590 service_name = get_conninfo_value("service");
4591 SetVariable(pset.vars, "SERVICE", service_name);
4592 if (service_name)
4593 pg_free(service_name);
4594
4595 service_file = get_conninfo_value("servicefile");
4596 SetVariable(pset.vars, "SERVICEFILE", service_file);
4597 if (service_file)
4598 pg_free(service_file);
4599
4600 /* this bit should match connection_warnings(): */
4601 /* Try to get full text form of version, might include "devel" etc */
4602 server_version = PQparameterStatus(pset.db, "server_version");
4603 /* Otherwise fall back on pset.sversion */
4604 if (!server_version)
4605 {
4606 formatPGVersionNumber(pset.sversion, true, vbuf, sizeof(vbuf));
4607 server_version = vbuf;
4608 }
4609 SetVariable(pset.vars, "SERVER_VERSION_NAME", server_version);
4610
4611 snprintf(vbuf, sizeof(vbuf), "%d", pset.sversion);
4612 SetVariable(pset.vars, "SERVER_VERSION_NUM", vbuf);
4613
4614 /* send stuff to it, too */
4617}
4618
4619/*
4620 * UnsyncVariables
4621 *
4622 * Clear variables that should be not be set when there is no connection.
4623 */
4624void
4626{
4627 SetVariable(pset.vars, "DBNAME", NULL);
4628 SetVariable(pset.vars, "SERVICE", NULL);
4629 SetVariable(pset.vars, "SERVICEFILE", NULL);
4630 SetVariable(pset.vars, "USER", NULL);
4631 SetVariable(pset.vars, "HOST", NULL);
4632 SetVariable(pset.vars, "PORT", NULL);
4633 SetVariable(pset.vars, "ENCODING", NULL);
4634 SetVariable(pset.vars, "SERVER_VERSION_NAME", NULL);
4635 SetVariable(pset.vars, "SERVER_VERSION_NUM", NULL);
4636}
4637
4638
4639/*
4640 * helper for do_edit(): actually invoke the editor
4641 *
4642 * Returns true on success, false if we failed to invoke the editor or
4643 * it returned nonzero status. (An error message is printed for failed-
4644 * to-invoke cases, but not if the editor returns nonzero status.)
4645 */
4646static bool
4647editFile(const char *fname, int lineno)
4648{
4649 const char *editorName;
4650 const char *editor_lineno_arg = NULL;
4651 char *sys;
4652 int result;
4653
4654 Assert(fname != NULL);
4655
4656 /* Find an editor to use */
4657 editorName = getenv("PSQL_EDITOR");
4658 if (!editorName)
4659 editorName = getenv("EDITOR");
4660 if (!editorName)
4661 editorName = getenv("VISUAL");
4662 if (!editorName)
4663 editorName = DEFAULT_EDITOR;
4664
4665 /* Get line number argument, if we need it. */
4666 if (lineno > 0)
4667 {
4668 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
4669#ifdef DEFAULT_EDITOR_LINENUMBER_ARG
4670 if (!editor_lineno_arg)
4671 editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
4672#endif
4673 if (!editor_lineno_arg)
4674 {
4675 pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
4676 return false;
4677 }
4678 }
4679
4680 /*
4681 * On Unix the EDITOR value should *not* be quoted, since it might include
4682 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
4683 * if necessary. But this policy is not very workable on Windows, due to
4684 * severe brain damage in their command shell plus the fact that standard
4685 * program paths include spaces.
4686 */
4687#ifndef WIN32
4688 if (lineno > 0)
4689 sys = psprintf("exec %s %s%d '%s'",
4690 editorName, editor_lineno_arg, lineno, fname);
4691 else
4692 sys = psprintf("exec %s '%s'",
4693 editorName, fname);
4694#else
4695 if (lineno > 0)
4696 sys = psprintf("\"%s\" %s%d \"%s\"",
4697 editorName, editor_lineno_arg, lineno, fname);
4698 else
4699 sys = psprintf("\"%s\" \"%s\"",
4700 editorName, fname);
4701#endif
4702 fflush(NULL);
4703 result = system(sys);
4704 if (result == -1)
4705 pg_log_error("could not start editor \"%s\"", editorName);
4706 else if (result == 127)
4707 pg_log_error("could not start /bin/sh");
4708 free(sys);
4709
4710 return result == 0;
4711}
4712
4713
4714/*
4715 * do_edit -- handler for \e
4716 *
4717 * If you do not specify a filename, the current query buffer will be copied
4718 * into a temporary file.
4719 *
4720 * After this function is done, the resulting file will be copied back into the
4721 * query buffer. As an exception to this, the query buffer will be emptied
4722 * if the file was not modified (or the editor failed) and the caller passes
4723 * "discard_on_quit" = true.
4724 *
4725 * If "edited" isn't NULL, *edited will be set to true if the query buffer
4726 * is successfully replaced.
4727 */
4728static bool
4729do_edit(const char *filename_arg, PQExpBuffer query_buf,
4730 int lineno, bool discard_on_quit, bool *edited)
4731{
4732 char fnametmp[MAXPGPATH];
4733 FILE *stream = NULL;
4734 const char *fname;
4735 bool error = false;
4736 int fd;
4737 struct stat before,
4738 after;
4739
4740 if (filename_arg)
4741 fname = filename_arg;
4742 else
4743 {
4744 /* make a temp file to edit */
4745#ifndef WIN32
4746 const char *tmpdir = getenv("TMPDIR");
4747
4748 if (!tmpdir)
4749 tmpdir = "/tmp";
4750#else
4751 char tmpdir[MAXPGPATH];
4752 int ret;
4753
4754 ret = GetTempPath(MAXPGPATH, tmpdir);
4755 if (ret == 0 || ret > MAXPGPATH)
4756 {
4757 pg_log_error("could not locate temporary directory: %s",
4758 !ret ? strerror(errno) : "");
4759 return false;
4760 }
4761#endif
4762
4763 /*
4764 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
4765 * current directory to the supplied path unless we use only
4766 * backslashes, so we do that.
4767 */
4768#ifndef WIN32
4769 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4770 "/", (int) getpid());
4771#else
4772 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4773 "" /* trailing separator already present */ , (int) getpid());
4774#endif
4775
4776 fname = (const char *) fnametmp;
4777
4778 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
4779 if (fd != -1)
4780 stream = fdopen(fd, "w");
4781
4782 if (fd == -1 || !stream)
4783 {
4784 pg_log_error("could not open temporary file \"%s\": %m", fname);
4785 error = true;
4786 }
4787 else
4788 {
4789 unsigned int ql = query_buf->len;
4790
4791 /* force newline-termination of what we send to editor */
4792 if (ql > 0 && query_buf->data[ql - 1] != '\n')
4793 {
4794 appendPQExpBufferChar(query_buf, '\n');
4795 ql++;
4796 }
4797
4798 if (fwrite(query_buf->data, 1, ql, stream) != ql)
4799 {
4800 pg_log_error("%s: %m", fname);
4801
4802 if (fclose(stream) != 0)
4803 pg_log_error("%s: %m", fname);
4804
4805 if (remove(fname) != 0)
4806 pg_log_error("%s: %m", fname);
4807
4808 error = true;
4809 }
4810 else if (fclose(stream) != 0)
4811 {
4812 pg_log_error("%s: %m", fname);
4813 if (remove(fname) != 0)
4814 pg_log_error("%s: %m", fname);
4815 error = true;
4816 }
4817 else
4818 {
4819 struct utimbuf ut;
4820
4821 /*
4822 * Try to set the file modification time of the temporary file
4823 * a few seconds in the past. Otherwise, the low granularity
4824 * (one second, or even worse on some filesystems) that we can
4825 * portably measure with stat(2) could lead us to not
4826 * recognize a modification, if the user typed very quickly.
4827 *
4828 * This is a rather unlikely race condition, so don't error
4829 * out if the utime(2) call fails --- that would make the cure
4830 * worse than the disease.
4831 */
4832 ut.modtime = ut.actime = time(NULL) - 2;
4833 (void) utime(fname, &ut);
4834 }
4835 }
4836 }
4837
4838 if (!error && stat(fname, &before) != 0)
4839 {
4840 pg_log_error("%s: %m", fname);
4841 error = true;
4842 }
4843
4844 /* call editor */
4845 if (!error)
4846 error = !editFile(fname, lineno);
4847
4848 if (!error && stat(fname, &after) != 0)
4849 {
4850 pg_log_error("%s: %m", fname);
4851 error = true;
4852 }
4853
4854 /* file was edited if the size or modification time has changed */
4855 if (!error &&
4856 (before.st_size != after.st_size ||
4857 before.st_mtime != after.st_mtime))
4858 {
4859 stream = fopen(fname, PG_BINARY_R);
4860 if (!stream)
4861 {
4862 pg_log_error("%s: %m", fname);
4863 error = true;
4864 }
4865 else
4866 {
4867 /* read file back into query_buf */
4868 char line[1024];
4869
4870 resetPQExpBuffer(query_buf);
4871 while (fgets(line, sizeof(line), stream) != NULL)
4872 appendPQExpBufferStr(query_buf, line);
4873
4874 if (ferror(stream))
4875 {
4876 pg_log_error("%s: %m", fname);
4877 error = true;
4878 resetPQExpBuffer(query_buf);
4879 }
4880 else if (edited)
4881 {
4882 *edited = true;
4883 }
4884
4885 fclose(stream);
4886 }
4887 }
4888 else
4889 {
4890 /*
4891 * If the file was not modified, and the caller requested it, discard
4892 * the query buffer.
4893 */
4894 if (discard_on_quit)
4895 resetPQExpBuffer(query_buf);
4896 }
4897
4898 /* remove temp file */
4899 if (!filename_arg)
4900 {
4901 if (remove(fname) == -1)
4902 {
4903 pg_log_error("%s: %m", fname);
4904 error = true;
4905 }
4906 }
4907
4908 return !error;
4909}
4910
4911
4912
4913/*
4914 * process_file
4915 *
4916 * Reads commands from filename and passes them to the main processing loop.
4917 * Handler for \i and \ir, but can be used for other things as well. Returns
4918 * MainLoop() error code.
4919 *
4920 * If use_relative_path is true and filename is not an absolute path, then open
4921 * the file from where the currently processed file (if any) is located.
4922 */
4923int
4924process_file(char *filename, bool use_relative_path)
4925{
4926 FILE *fd;
4927 int result;
4928 char *oldfilename;
4929 char relpath[MAXPGPATH];
4930
4931 if (!filename)
4932 {
4933 fd = stdin;
4934 filename = NULL;
4935 }
4936 else if (strcmp(filename, "-") != 0)
4937 {
4939
4940 /*
4941 * If we were asked to resolve the pathname relative to the location
4942 * of the currently executing script, and there is one, and this is a
4943 * relative pathname, then prepend all but the last pathname component
4944 * of the current script to this pathname.
4945 */
4946 if (use_relative_path && pset.inputfile &&
4948 {
4953
4954 filename = relpath;
4955 }
4956
4957 fd = fopen(filename, PG_BINARY_R);
4958
4959 if (!fd)
4960 {
4961 pg_log_error("%s: %m", filename);
4962 return EXIT_FAILURE;
4963 }
4964 }
4965 else
4966 {
4967 fd = stdin;
4968 filename = "<stdin>"; /* for future error messages */
4969 }
4970
4971 oldfilename = pset.inputfile;
4973
4975
4976 result = MainLoop(fd);
4977
4978 if (fd != stdin)
4979 fclose(fd);
4980
4981 pset.inputfile = oldfilename;
4982
4984
4985 return result;
4986}
4987
4988
4989
4990static const char *
4992{
4993 switch (in)
4994 {
4995 case PRINT_NOTHING:
4996 return "nothing";
4997 break;
4998 case PRINT_ALIGNED:
4999 return "aligned";
5000 break;
5001 case PRINT_ASCIIDOC:
5002 return "asciidoc";
5003 break;
5004 case PRINT_CSV:
5005 return "csv";
5006 break;
5007 case PRINT_HTML:
5008 return "html";
5009 break;
5010 case PRINT_LATEX:
5011 return "latex";
5012 break;
5014 return "latex-longtable";
5015 break;
5016 case PRINT_TROFF_MS:
5017 return "troff-ms";
5018 break;
5019 case PRINT_UNALIGNED:
5020 return "unaligned";
5021 break;
5022 case PRINT_WRAPPED:
5023 return "wrapped";
5024 break;
5025 }
5026 return "unknown";
5027}
5028
5029/*
5030 * Parse entered Unicode linestyle. If ok, update *linestyle and return
5031 * true, else return false.
5032 */
5033static bool
5034set_unicode_line_style(const char *value, size_t vallen,
5035 unicode_linestyle *linestyle)
5036{
5037 if (pg_strncasecmp("single", value, vallen) == 0)
5038 *linestyle = UNICODE_LINESTYLE_SINGLE;
5039 else if (pg_strncasecmp("double", value, vallen) == 0)
5040 *linestyle = UNICODE_LINESTYLE_DOUBLE;
5041 else
5042 return false;
5043 return true;
5044}
5045
5046static const char *
5048{
5049 switch (linestyle)
5050 {
5052 return "single";
5053 break;
5055 return "double";
5056 break;
5057 }
5058 return "unknown";
5059}
5060
5061/*
5062 * do_pset
5063 *
5064 * Performs the assignment "param = value", where value could be NULL;
5065 * for some params that has an effect such as inversion, for others
5066 * it does nothing.
5067 *
5068 * Adjusts the state of the formatting options at *popt. (In practice that
5069 * is always pset.popt, but maybe someday it could be different.)
5070 *
5071 * If successful and quiet is false, then invokes printPsetInfo() to report
5072 * the change.
5073 *
5074 * Returns true if successful, else false (eg for invalid param or value).
5075 */
5076bool
5077do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
5078{
5079 size_t vallen = 0;
5080
5081 Assert(param != NULL);
5082
5083 if (value)
5084 vallen = strlen(value);
5085
5086 /* set format */
5087 if (strcmp(param, "format") == 0)
5088 {
5089 static const struct fmt
5090 {
5091 const char *name;
5092 enum printFormat number;
5093 } formats[] =
5094 {
5095 /* remember to update error message below when adding more */
5096 {"aligned", PRINT_ALIGNED},
5097 {"asciidoc", PRINT_ASCIIDOC},
5098 {"csv", PRINT_CSV},
5099 {"html", PRINT_HTML},
5100 {"latex", PRINT_LATEX},
5101 {"troff-ms", PRINT_TROFF_MS},
5102 {"unaligned", PRINT_UNALIGNED},
5103 {"wrapped", PRINT_WRAPPED}
5104 };
5105
5106 if (!value)
5107 ;
5108 else
5109 {
5110 int match_pos = -1;
5111
5112 for (int i = 0; i < lengthof(formats); i++)
5113 {
5114 if (pg_strncasecmp(formats[i].name, value, vallen) == 0)
5115 {
5116 if (match_pos < 0)
5117 match_pos = i;
5118 else
5119 {
5120 pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
5121 value,
5122 formats[match_pos].name, formats[i].name);
5123 return false;
5124 }
5125 }
5126 }
5127 if (match_pos >= 0)
5128 popt->topt.format = formats[match_pos].number;
5129 else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
5130 {
5131 /*
5132 * We must treat latex-longtable specially because latex is a
5133 * prefix of it; if both were in the table above, we'd think
5134 * "latex" is ambiguous.
5135 */
5137 }
5138 else
5139 {
5140 pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
5141 return false;
5142 }
5143 }
5144 }
5145
5146 /* set table line style */
5147 else if (strcmp(param, "linestyle") == 0)
5148 {
5149 if (!value)
5150 ;
5151 else if (pg_strncasecmp("ascii", value, vallen) == 0)
5153 else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
5155 else if (pg_strncasecmp("unicode", value, vallen) == 0)
5156 popt->topt.line_style = &pg_utf8format;
5157 else
5158 {
5159 pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
5160 return false;
5161 }
5162 }
5163
5164 /* set unicode border line style */
5165 else if (strcmp(param, "unicode_border_linestyle") == 0)
5166 {
5167 if (!value)
5168 ;
5169 else if (set_unicode_line_style(value, vallen,
5171 refresh_utf8format(&(popt->topt));
5172 else
5173 {
5174 pg_log_error("\\pset: allowed Unicode border line styles are single, double");
5175 return false;
5176 }
5177 }
5178
5179 /* set unicode column line style */
5180 else if (strcmp(param, "unicode_column_linestyle") == 0)
5181 {
5182 if (!value)
5183 ;
5184 else if (set_unicode_line_style(value, vallen,
5186 refresh_utf8format(&(popt->topt));
5187 else
5188 {
5189 pg_log_error("\\pset: allowed Unicode column line styles are single, double");
5190 return false;
5191 }
5192 }
5193
5194 /* set unicode header line style */
5195 else if (strcmp(param, "unicode_header_linestyle") == 0)
5196 {
5197 if (!value)
5198 ;
5199 else if (set_unicode_line_style(value, vallen,
5201 refresh_utf8format(&(popt->topt));
5202 else
5203 {
5204 pg_log_error("\\pset: allowed Unicode header line styles are single, double");
5205 return false;
5206 }
5207 }
5208
5209 /* set border style/width */
5210 else if (strcmp(param, "border") == 0)
5211 {
5212 if (value)
5213 popt->topt.border = atoi(value);
5214 }
5215
5216 /* set expanded/vertical mode */
5217 else if (strcmp(param, "x") == 0 ||
5218 strcmp(param, "expanded") == 0 ||
5219 strcmp(param, "vertical") == 0)
5220 {
5221 if (value && pg_strcasecmp(value, "auto") == 0)
5222 popt->topt.expanded = 2;
5223 else if (value)
5224 {
5225 bool on_off;
5226
5227 if (ParseVariableBool(value, NULL, &on_off))
5228 popt->topt.expanded = on_off ? 1 : 0;
5229 else
5230 {
5231 PsqlVarEnumError(param, value, "on, off, auto");
5232 return false;
5233 }
5234 }
5235 else
5236 popt->topt.expanded = !popt->topt.expanded;
5237 }
5238
5239 /* header line width in expanded mode */
5240 else if (strcmp(param, "xheader_width") == 0)
5241 {
5242 if (!value)
5243 ;
5244 else if (pg_strcasecmp(value, "full") == 0)
5246 else if (pg_strcasecmp(value, "column") == 0)
5248 else if (pg_strcasecmp(value, "page") == 0)
5250 else
5251 {
5252 int intval = atoi(value);
5253
5254 if (intval == 0)
5255 {
5256 pg_log_error("\\pset: allowed xheader_width values are \"%s\" (default), \"%s\", \"%s\", or a number specifying the exact width", "full", "column", "page");
5257 return false;
5258 }
5259
5261 popt->topt.expanded_header_exact_width = intval;
5262 }
5263 }
5264
5265 /* field separator for CSV format */
5266 else if (strcmp(param, "csv_fieldsep") == 0)
5267 {
5268 if (value)
5269 {
5270 /* CSV separator has to be a one-byte character */
5271 if (strlen(value) != 1)
5272 {
5273 pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
5274 return false;
5275 }
5276 if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
5277 {
5278 pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
5279 return false;
5280 }
5281 popt->topt.csvFieldSep[0] = value[0];
5282 }
5283 }
5284
5285 /* locale-aware numeric output */
5286 else if (strcmp(param, "numericlocale") == 0)
5287 {
5288 if (value)
5289 return ParseVariableBool(value, param, &popt->topt.numericLocale);
5290 else
5291 popt->topt.numericLocale = !popt->topt.numericLocale;
5292 }
5293
5294 /* null display */
5295 else if (strcmp(param, "null") == 0)
5296 {
5297 if (value)
5298 {
5299 free(popt->nullPrint);
5300 popt->nullPrint = pg_strdup(value);
5301 }
5302 }
5303
5304 /* 'false' display */
5305 else if (strcmp(param, "display_false") == 0)
5306 {
5307 if (value)
5308 {
5309 free(popt->falsePrint);
5310 popt->falsePrint = pg_strdup(value);
5311 }
5312 }
5313
5314 /* 'true' display */
5315 else if (strcmp(param, "display_true") == 0)
5316 {
5317 if (value)
5318 {
5319 free(popt->truePrint);
5320 popt->truePrint = pg_strdup(value);
5321 }
5322 }
5323
5324 /* field separator for unaligned text */
5325 else if (strcmp(param, "fieldsep") == 0)
5326 {
5327 if (value)
5328 {
5329 free(popt->topt.fieldSep.separator);
5331 popt->topt.fieldSep.separator_zero = false;
5332 }
5333 }
5334
5335 else if (strcmp(param, "fieldsep_zero") == 0)
5336 {
5337 free(popt->topt.fieldSep.separator);
5338 popt->topt.fieldSep.separator = NULL;
5339 popt->topt.fieldSep.separator_zero = true;
5340 }
5341
5342 /* record separator for unaligned text */
5343 else if (strcmp(param, "recordsep") == 0)
5344 {
5345 if (value)
5346 {
5349 popt->topt.recordSep.separator_zero = false;
5350 }
5351 }
5352
5353 else if (strcmp(param, "recordsep_zero") == 0)
5354 {
5356 popt->topt.recordSep.separator = NULL;
5357 popt->topt.recordSep.separator_zero = true;
5358 }
5359
5360 /* toggle between full and tuples-only format */
5361 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
5362 {
5363 if (value)
5364 return ParseVariableBool(value, param, &popt->topt.tuples_only);
5365 else
5366 popt->topt.tuples_only = !popt->topt.tuples_only;
5367 }
5368
5369 /* set title override */
5370 else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
5371 {
5372 free(popt->title);
5373 if (!value)
5374 popt->title = NULL;
5375 else
5376 popt->title = pg_strdup(value);
5377 }
5378
5379 /* set HTML table tag options */
5380 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
5381 {
5382 free(popt->topt.tableAttr);
5383 if (!value)
5384 popt->topt.tableAttr = NULL;
5385 else
5386 popt->topt.tableAttr = pg_strdup(value);
5387 }
5388
5389 /* toggle use of pager */
5390 else if (strcmp(param, "pager") == 0)
5391 {
5392 if (value && pg_strcasecmp(value, "always") == 0)
5393 popt->topt.pager = 2;
5394 else if (value)
5395 {
5396 bool on_off;
5397
5398 if (!ParseVariableBool(value, NULL, &on_off))
5399 {
5400 PsqlVarEnumError(param, value, "on, off, always");
5401 return false;
5402 }
5403 popt->topt.pager = on_off ? 1 : 0;
5404 }
5405 else if (popt->topt.pager == 1)
5406 popt->topt.pager = 0;
5407 else
5408 popt->topt.pager = 1;
5409 }
5410
5411 /* set minimum lines for pager use */
5412 else if (strcmp(param, "pager_min_lines") == 0)
5413 {
5414 if (value &&
5415 !ParseVariableNum(value, "pager_min_lines", &popt->topt.pager_min_lines))
5416 return false;
5417 }
5418
5419 /* disable "(x rows)" footer */
5420 else if (strcmp(param, "footer") == 0)
5421 {
5422 if (value)
5423 return ParseVariableBool(value, param, &popt->topt.default_footer);
5424 else
5425 popt->topt.default_footer = !popt->topt.default_footer;
5426 }
5427
5428 /* set border style/width */
5429 else if (strcmp(param, "columns") == 0)
5430 {
5431 if (value)
5432 popt->topt.columns = atoi(value);
5433 }
5434 else
5435 {
5436 pg_log_error("\\pset: unknown option: %s", param);
5437 return false;
5438 }
5439
5440 if (!quiet)
5441 printPsetInfo(param, &pset.popt);
5442
5443 return true;
5444}
5445
5446/*
5447 * printPsetInfo: print the state of the "param" formatting parameter in popt.
5448 */
5449static bool
5450printPsetInfo(const char *param, printQueryOpt *popt)
5451{
5452 Assert(param != NULL);
5453
5454 /* show border style/width */
5455 if (strcmp(param, "border") == 0)
5456 printf(_("Border style is %d.\n"), popt->topt.border);
5457
5458 /* show the target width for the wrapped format */
5459 else if (strcmp(param, "columns") == 0)
5460 {
5461 if (!popt->topt.columns)
5462 printf(_("Target width is unset.\n"));
5463 else
5464 printf(_("Target width is %d.\n"), popt->topt.columns);
5465 }
5466
5467 /* show expanded/vertical mode */
5468 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
5469 {
5470 if (popt->topt.expanded == 1)
5471 printf(_("Expanded display is on.\n"));
5472 else if (popt->topt.expanded == 2)
5473 printf(_("Expanded display is used automatically.\n"));
5474 else
5475 printf(_("Expanded display is off.\n"));
5476 }
5477
5478 /* show xheader width value */
5479 else if (strcmp(param, "xheader_width") == 0)
5480 {
5482 printf(_("Expanded header width is \"%s\".\n"), "full");
5484 printf(_("Expanded header width is \"%s\".\n"), "column");
5486 printf(_("Expanded header width is \"%s\".\n"), "page");
5488 printf(_("Expanded header width is %d.\n"), popt->topt.expanded_header_exact_width);
5489 }
5490
5491 /* show field separator for CSV format */
5492 else if (strcmp(param, "csv_fieldsep") == 0)
5493 {
5494 printf(_("Field separator for CSV is \"%s\".\n"),
5495 popt->topt.csvFieldSep);
5496 }
5497
5498 /* show boolean 'false' display */
5499 else if (strcmp(param, "display_false") == 0)
5500 {
5501 printf(_("Boolean false display is \"%s\".\n"),
5502 popt->falsePrint ? popt->falsePrint : "f");
5503 }
5504
5505 /* show boolean 'true' display */
5506 else if (strcmp(param, "display_true") == 0)
5507 {
5508 printf(_("Boolean true display is \"%s\".\n"),
5509 popt->truePrint ? popt->truePrint : "t");
5510 }
5511
5512 /* show field separator for unaligned text */
5513 else if (strcmp(param, "fieldsep") == 0)
5514 {
5515 if (popt->topt.fieldSep.separator_zero)
5516 printf(_("Field separator is zero byte.\n"));
5517 else
5518 printf(_("Field separator is \"%s\".\n"),
5519 popt->topt.fieldSep.separator);
5520 }
5521
5522 else if (strcmp(param, "fieldsep_zero") == 0)
5523 {
5524 printf(_("Field separator is zero byte.\n"));
5525 }
5526
5527 /* show disable "(x rows)" footer */
5528 else if (strcmp(param, "footer") == 0)
5529 {
5530 if (popt->topt.default_footer)
5531 printf(_("Default footer is on.\n"));
5532 else
5533 printf(_("Default footer is off.\n"));
5534 }
5535
5536 /* show format */
5537 else if (strcmp(param, "format") == 0)
5538 {
5539 printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
5540 }
5541
5542 /* show table line style */
5543 else if (strcmp(param, "linestyle") == 0)
5544 {
5545 printf(_("Line style is %s.\n"),
5546 get_line_style(&popt->topt)->name);
5547 }
5548
5549 /* show null display */
5550 else if (strcmp(param, "null") == 0)
5551 {
5552 printf(_("Null display is \"%s\".\n"),
5553 popt->nullPrint ? popt->nullPrint : "");
5554 }
5555
5556 /* show locale-aware numeric output */
5557 else if (strcmp(param, "numericlocale") == 0)
5558 {
5559 if (popt->topt.numericLocale)
5560 printf(_("Locale-adjusted numeric output is on.\n"));
5561 else
5562 printf(_("Locale-adjusted numeric output is off.\n"));
5563 }
5564
5565 /* show toggle use of pager */
5566 else if (strcmp(param, "pager") == 0)
5567 {
5568 if (popt->topt.pager == 1)
5569 printf(_("Pager is used for long output.\n"));
5570 else if (popt->topt.pager == 2)
5571 printf(_("Pager is always used.\n"));
5572 else
5573 printf(_("Pager usage is off.\n"));
5574 }
5575
5576 /* show minimum lines for pager use */
5577 else if (strcmp(param, "pager_min_lines") == 0)
5578 {
5579 printf(ngettext("Pager won't be used for less than %d line.\n",
5580 "Pager won't be used for less than %d lines.\n",
5581 popt->topt.pager_min_lines),
5582 popt->topt.pager_min_lines);
5583 }
5584
5585 /* show record separator for unaligned text */
5586 else if (strcmp(param, "recordsep") == 0)
5587 {
5588 if (popt->topt.recordSep.separator_zero)
5589 printf(_("Record separator is zero byte.\n"));
5590 else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
5591 printf(_("Record separator is <newline>.\n"));
5592 else
5593 printf(_("Record separator is \"%s\".\n"),
5594 popt->topt.recordSep.separator);
5595 }
5596
5597 else if (strcmp(param, "recordsep_zero") == 0)
5598 {
5599 printf(_("Record separator is zero byte.\n"));
5600 }
5601
5602 /* show HTML table tag options */
5603 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
5604 {
5605 if (popt->topt.tableAttr)
5606 printf(_("Table attributes are \"%s\".\n"),
5607 popt->topt.tableAttr);
5608 else
5609 printf(_("Table attributes unset.\n"));
5610 }
5611
5612 /* show title override */
5613 else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
5614 {
5615 if (popt->title)
5616 printf(_("Title is \"%s\".\n"), popt->title);
5617 else
5618 printf(_("Title is unset.\n"));
5619 }
5620
5621 /* show toggle between full and tuples-only format */
5622 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
5623 {
5624 if (popt->topt.tuples_only)
5625 printf(_("Tuples only is on.\n"));
5626 else
5627 printf(_("Tuples only is off.\n"));
5628 }
5629
5630 /* Unicode style formatting */
5631 else if (strcmp(param, "unicode_border_linestyle") == 0)
5632 {
5633 printf(_("Unicode border line style is \"%s\".\n"),
5635 }
5636
5637 else if (strcmp(param, "unicode_column_linestyle") == 0)
5638 {
5639 printf(_("Unicode column line style is \"%s\".\n"),
5641 }
5642
5643 else if (strcmp(param, "unicode_header_linestyle") == 0)
5644 {
5645 printf(_("Unicode header line style is \"%s\".\n"),
5647 }
5648
5649 else
5650 {
5651 pg_log_error("\\pset: unknown option: %s", param);
5652 return false;
5653 }
5654
5655 return true;
5656}
5657
5658/*
5659 * savePsetInfo: make a malloc'd copy of the data in *popt.
5660 *
5661 * Possibly this should be somewhere else, but it's a bit specific to psql.
5662 */
5665{
5666 printQueryOpt *save;
5667
5668 save = (printQueryOpt *) pg_malloc(sizeof(printQueryOpt));
5669
5670 /* Flat-copy all the scalar fields, then duplicate sub-structures. */
5671 memcpy(save, popt, sizeof(printQueryOpt));
5672
5673 /* topt.line_style points to const data that need not be duplicated */
5674 if (popt->topt.fieldSep.separator)
5676 if (popt->topt.recordSep.separator)
5678 if (popt->topt.tableAttr)
5679 save->topt.tableAttr = pg_strdup(popt->topt.tableAttr);
5680 if (popt->nullPrint)
5681 save->nullPrint = pg_strdup(popt->nullPrint);
5682 if (popt->title)
5683 save->title = pg_strdup(popt->title);
5684
5685 /*
5686 * footers and translate_columns are never set in psql's print settings,
5687 * so we needn't write code to duplicate them.
5688 */
5689 Assert(popt->footers == NULL);
5690 Assert(popt->translate_columns == NULL);
5691
5692 return save;
5693}
5694
5695/*
5696 * restorePsetInfo: restore *popt from the previously-saved copy *save,
5697 * then free *save.
5698 */
5699void
5701{
5702 /* Free all the old data we're about to overwrite the pointers to. */
5703
5704 /* topt.line_style points to const data that need not be duplicated */
5705 free(popt->topt.fieldSep.separator);
5707 free(popt->topt.tableAttr);
5708 free(popt->nullPrint);
5709 free(popt->title);
5710
5711 /*
5712 * footers and translate_columns are never set in psql's print settings,
5713 * so we needn't write code to duplicate them.
5714 */
5715 Assert(popt->footers == NULL);
5716 Assert(popt->translate_columns == NULL);
5717
5718 /* Now we may flat-copy all the fields, including pointers. */
5719 memcpy(popt, save, sizeof(printQueryOpt));
5720
5721 /* Lastly, free "save" ... but its sub-structures now belong to popt. */
5722 free(save);
5723}
5724
5725static const char *
5727{
5728 return val ? "on" : "off";
5729}
5730
5731
5732static char *
5734{
5735 char *ret = pg_malloc(strlen(str) * 2 + 3);
5736 char *r = ret;
5737
5738 *r++ = '\'';
5739
5740 for (; *str; str++)
5741 {
5742 if (*str == '\n')
5743 {
5744 *r++ = '\\';
5745 *r++ = 'n';
5746 }
5747 else if (*str == '\'')
5748 {
5749 *r++ = '\\';
5750 *r++ = '\'';
5751 }
5752 else
5753 *r++ = *str;
5754 }
5755
5756 *r++ = '\'';
5757 *r = '\0';
5758
5759 return ret;
5760}
5761
5762
5763/*
5764 * Return a malloc'ed string for the \pset value.
5765 *
5766 * Note that for some string parameters, print.c distinguishes between unset
5767 * and empty string, but for others it doesn't. This function should produce
5768 * output that produces the correct setting when fed back into \pset.
5769 */
5770static char *
5771pset_value_string(const char *param, printQueryOpt *popt)
5772{
5773 Assert(param != NULL);
5774
5775 if (strcmp(param, "border") == 0)
5776 return psprintf("%d", popt->topt.border);
5777 else if (strcmp(param, "columns") == 0)
5778 return psprintf("%d", popt->topt.columns);
5779 else if (strcmp(param, "csv_fieldsep") == 0)
5780 return pset_quoted_string(popt->topt.csvFieldSep);
5781 else if (strcmp(param, "display_false") == 0)
5782 return pset_quoted_string(popt->falsePrint ? popt->falsePrint : "f");
5783 else if (strcmp(param, "display_true") == 0)
5784 return pset_quoted_string(popt->truePrint ? popt->truePrint : "t");
5785 else if (strcmp(param, "expanded") == 0)
5786 return pstrdup(popt->topt.expanded == 2
5787 ? "auto"
5788 : pset_bool_string(popt->topt.expanded));
5789 else if (strcmp(param, "fieldsep") == 0)
5791 ? popt->topt.fieldSep.separator
5792 : "");
5793 else if (strcmp(param, "fieldsep_zero") == 0)
5795 else if (strcmp(param, "footer") == 0)
5797 else if (strcmp(param, "format") == 0)
5798 return pstrdup(_align2string(popt->topt.format));
5799 else if (strcmp(param, "linestyle") == 0)
5800 return pstrdup(get_line_style(&popt->topt)->name);
5801 else if (strcmp(param, "null") == 0)
5802 return pset_quoted_string(popt->nullPrint
5803 ? popt->nullPrint
5804 : "");
5805 else if (strcmp(param, "numericlocale") == 0)
5807 else if (strcmp(param, "pager") == 0)
5808 return psprintf("%d", popt->topt.pager);
5809 else if (strcmp(param, "pager_min_lines") == 0)
5810 return psprintf("%d", popt->topt.pager_min_lines);
5811 else if (strcmp(param, "recordsep") == 0)
5813 ? popt->topt.recordSep.separator
5814 : "");
5815 else if (strcmp(param, "recordsep_zero") == 0)
5817 else if (strcmp(param, "tableattr") == 0)
5818 return popt->topt.tableAttr ? pset_quoted_string(popt->topt.tableAttr) : pstrdup("");
5819 else if (strcmp(param, "title") == 0)
5820 return popt->title ? pset_quoted_string(popt->title) : pstrdup("");
5821 else if (strcmp(param, "tuples_only") == 0)
5823 else if (strcmp(param, "unicode_border_linestyle") == 0)
5825 else if (strcmp(param, "unicode_column_linestyle") == 0)
5827 else if (strcmp(param, "unicode_header_linestyle") == 0)
5829 else if (strcmp(param, "xheader_width") == 0)
5830 {
5832 return pstrdup("full");
5834 return pstrdup("column");
5836 return pstrdup("page");
5837 else
5838 {
5839 /* must be PRINT_XHEADER_EXACT_WIDTH */
5840 char wbuff[32];
5841
5842 snprintf(wbuff, sizeof(wbuff), "%d",
5844 return pstrdup(wbuff);
5845 }
5846 }
5847 else
5848 return pstrdup("ERROR");
5849}
5850
5851
5852
5853#ifndef WIN32
5854#define DEFAULT_SHELL "/bin/sh"
5855#else
5856/*
5857 * CMD.EXE is in different places in different Win32 releases so we
5858 * have to rely on the path to find it.
5859 */
5860#define DEFAULT_SHELL "cmd.exe"
5861#endif
5862
5863static bool
5864do_shell(const char *command)
5865{
5866 int result;
5867
5868 fflush(NULL);
5869 if (!command)
5870 {
5871 char *sys;
5872 const char *shellName;
5873
5874 shellName = getenv("SHELL");
5875#ifdef WIN32
5876 if (shellName == NULL)
5877 shellName = getenv("COMSPEC");
5878#endif
5879 if (shellName == NULL)
5880 shellName = DEFAULT_SHELL;
5881
5882 /* See EDITOR handling comment for an explanation */
5883#ifndef WIN32
5884 sys = psprintf("exec %s", shellName);
5885#else
5886 sys = psprintf("\"%s\"", shellName);
5887#endif
5888 result = system(sys);
5889 free(sys);
5890 }
5891 else
5892 result = system(command);
5893
5895
5896 if (result == 127 || result == -1)
5897 {
5898 pg_log_error("\\!: failed");
5899 return false;
5900 }
5901 return true;
5902}
5903
5904/*
5905 * do_watch -- handler for \watch
5906 *
5907 * We break this out of exec_command to avoid having to plaster "volatile"
5908 * onto a bunch of exec_command's variables to silence stupider compilers.
5909 *
5910 * "sleep" is the amount of time to sleep during each loop, measured in
5911 * seconds. The internals of this function should use "sleep_ms" for
5912 * precise sleep time calculations.
5913 */
5914static bool
5915do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
5916{
5917 long sleep_ms = (long) (sleep * 1000);
5918 printQueryOpt myopt = pset.popt;
5919 const char *strftime_fmt;
5920 const char *user_title;
5921 char *title;
5922 const char *pagerprog = NULL;
5923 FILE *pagerpipe = NULL;
5924 int title_len;
5925 int res = 0;
5926 bool done = false;
5927#ifndef WIN32
5928 sigset_t sigalrm_sigchld_sigint;
5929 sigset_t sigalrm_sigchld;
5930 sigset_t sigint;
5931 struct itimerval interval;
5932#endif
5933
5934 if (!query_buf || query_buf->len <= 0)
5935 {
5936 pg_log_error("\\watch cannot be used with an empty query");
5937 return false;
5938 }
5939
5940#ifndef WIN32
5941 sigemptyset(&sigalrm_sigchld_sigint);
5942 sigaddset(&sigalrm_sigchld_sigint, SIGCHLD);
5943 sigaddset(&sigalrm_sigchld_sigint, SIGALRM);
5944 sigaddset(&sigalrm_sigchld_sigint, SIGINT);
5945
5946 sigemptyset(&sigalrm_sigchld);
5947 sigaddset(&sigalrm_sigchld, SIGCHLD);
5948 sigaddset(&sigalrm_sigchld, SIGALRM);
5949
5950 sigemptyset(&sigint);
5951 sigaddset(&sigint, SIGINT);
5952
5953 /*
5954 * Block SIGALRM and SIGCHLD before we start the timer and the pager (if
5955 * configured), to avoid races. sigwait() will receive them.
5956 */
5957 sigprocmask(SIG_BLOCK, &sigalrm_sigchld, NULL);
5958
5959 /*
5960 * Set a timer to interrupt sigwait() so we can run the query at the
5961 * requested intervals.
5962 */
5963 interval.it_value.tv_sec = sleep_ms / 1000;
5964 interval.it_value.tv_usec = (sleep_ms % 1000) * 1000;
5965 interval.it_interval = interval.it_value;
5966 if (setitimer(ITIMER_REAL, &interval, NULL) < 0)
5967 {
5968 pg_log_error("could not set timer: %m");
5969 done = true;
5970 }
5971#endif
5972
5973 /*
5974 * For \watch, we ignore the size of the result and always use the pager
5975 * as long as we're talking to a terminal and "\pset pager" is enabled.
5976 * However, we'll only use the pager identified by PSQL_WATCH_PAGER. We
5977 * ignore the regular PSQL_PAGER or PAGER environment variables, because
5978 * traditional pagers probably won't be very useful for showing a stream
5979 * of results.
5980 */
5981#ifndef WIN32
5982 pagerprog = getenv("PSQL_WATCH_PAGER");
5983 /* if variable is empty or all-white-space, don't use pager */
5984 if (pagerprog && strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
5985 pagerprog = NULL;
5986#endif
5987 if (pagerprog && myopt.topt.pager &&
5988 isatty(fileno(stdin)) && isatty(fileno(stdout)))
5989 {
5990 fflush(NULL);
5992 pagerpipe = popen(pagerprog, "w");
5993
5994 if (!pagerpipe)
5995 /* silently proceed without pager */
5997 }
5998
5999 /*
6000 * Choose format for timestamps. We might eventually make this a \pset
6001 * option. In the meantime, using a variable for the format suppresses
6002 * overly-anal-retentive gcc warnings about %c being Y2K sensitive.
6003 */
6004 strftime_fmt = "%c";
6005
6006 /*
6007 * Set up rendering options, in particular, disable the pager unless
6008 * PSQL_WATCH_PAGER was successfully launched.
6009 */
6010 if (!pagerpipe)
6011 myopt.topt.pager = 0;
6012
6013 /*
6014 * If there's a title in the user configuration, make sure we have room
6015 * for it in the title buffer. Allow 128 bytes for the timestamp plus 128
6016 * bytes for the rest.
6017 */
6018 user_title = myopt.title;
6019 title_len = (user_title ? strlen(user_title) : 0) + 256;
6020 title = pg_malloc(title_len);
6021
6022 /* Loop to run query and then sleep awhile */
6023 while (!done)
6024 {
6025 time_t timer;
6026 char timebuf[128];
6027
6028 /*
6029 * Prepare title for output. Note that we intentionally include a
6030 * newline at the end of the title; this is somewhat historical but it
6031 * makes for reasonably nicely formatted output in simple cases.
6032 */
6033 timer = time(NULL);
6034 strftime(timebuf, sizeof(timebuf), strftime_fmt, localtime(&timer));
6035
6036 if (user_title)
6037 snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
6038 user_title, timebuf, sleep_ms / 1000.0);
6039 else
6040 snprintf(title, title_len, _("%s (every %gs)\n"),
6041 timebuf, sleep_ms / 1000.0);
6042 myopt.title = title;
6043
6044 /* Run the query and print out the result */
6045 res = PSQLexecWatch(query_buf->data, &myopt, pagerpipe, min_rows);
6046
6047 /*
6048 * PSQLexecWatch handles the case where we can no longer repeat the
6049 * query, and returns 0 or -1.
6050 */
6051 if (res <= 0)
6052 break;
6053
6054 /* If we have iteration count, check that it's not exceeded yet */
6055 if (iter && (--iter <= 0))
6056 break;
6057
6058 /* Quit if error on pager pipe (probably pager has quit) */
6059 if (pagerpipe && ferror(pagerpipe))
6060 break;
6061
6062 /* Tight loop, no wait needed */
6063 if (sleep_ms == 0)
6064 continue;
6065
6066#ifdef WIN32
6067
6068 /*
6069 * Wait a while before running the query again. Break the sleep into
6070 * short intervals (at most 1s); that's probably unnecessary since
6071 * pg_usleep is interruptible on Windows, but it's cheap insurance.
6072 */
6073 for (long i = sleep_ms; i > 0;)
6074 {
6075 long s = Min(i, 1000L);
6076
6077 pg_usleep(s * 1000L);
6078 if (cancel_pressed)
6079 {
6080 done = true;
6081 break;
6082 }
6083 i -= s;
6084 }
6085#else
6086 /* sigwait() will handle SIGINT. */
6087 sigprocmask(SIG_BLOCK, &sigint, NULL);
6088 if (cancel_pressed)
6089 done = true;
6090
6091 /* Wait for SIGINT, SIGCHLD or SIGALRM. */
6092 while (!done)
6093 {
6094 int signal_received;
6095
6096 errno = sigwait(&sigalrm_sigchld_sigint, &signal_received);
6097 if (errno != 0)
6098 {
6099 /* Some other signal arrived? */
6100 if (errno == EINTR)
6101 continue;
6102 else
6103 {
6104 pg_log_error("could not wait for signals: %m");
6105 done = true;
6106 break;
6107 }
6108 }
6109 /* On ^C or pager exit, it's time to stop running the query. */
6110 if (signal_received == SIGINT || signal_received == SIGCHLD)
6111 done = true;
6112 /* Otherwise, we must have SIGALRM. Time to run the query again. */
6113 break;
6114 }
6115
6116 /* Unblock SIGINT so that slow queries can be interrupted. */
6117 sigprocmask(SIG_UNBLOCK, &sigint, NULL);
6118#endif
6119 }
6120
6121 if (pagerpipe)
6122 {
6123 pclose(pagerpipe);
6125 }
6126 else
6127 {
6128 /*
6129 * If the terminal driver echoed "^C", libedit/libreadline might be
6130 * confused about the cursor position. Therefore, inject a newline
6131 * before the next prompt is displayed. We only do this when not
6132 * using a pager, because pagers are expected to restore the screen to
6133 * a sane state on exit.
6134 */
6135 fprintf(stdout, "\n");
6136 fflush(stdout);
6137 }
6138
6139#ifndef WIN32
6140 /* Disable the interval timer. */
6141 memset(&interval, 0, sizeof(interval));
6143 /* Unblock SIGINT, SIGCHLD and SIGALRM. */
6144 sigprocmask(SIG_UNBLOCK, &sigalrm_sigchld_sigint, NULL);
6145#endif
6146
6147 pg_free(title);
6148 return (res >= 0);
6149}
6150
6151/*
6152 * a little code borrowed from PSQLexec() to manage ECHO_HIDDEN output.
6153 * returns true unless we have ECHO_HIDDEN_NOEXEC.
6154 */
6155static bool
6156echo_hidden_command(const char *query)
6157{
6159 {
6160 printf(_("/******** QUERY *********/\n"
6161 "%s\n"
6162 "/************************/\n\n"), query);
6163 fflush(stdout);
6164 if (pset.logfile)
6165 {
6167 _("/******** QUERY *********/\n"
6168 "%s\n"
6169 "/************************/\n\n"), query);
6170 fflush(pset.logfile);
6171 }
6172
6174 return false;
6175 }
6176 return true;
6177}
6178
6179/*
6180 * Look up the object identified by obj_type and desc. If successful,
6181 * store its OID in *obj_oid and return true, else return false.
6182 *
6183 * Note that we'll fail if the object doesn't exist OR if there are multiple
6184 * matching candidates OR if there's something syntactically wrong with the
6185 * object description; unfortunately it can be hard to tell the difference.
6186 */
6187static bool
6188lookup_object_oid(EditableObjectType obj_type, const char *desc,
6189 Oid *obj_oid)
6190{
6191 bool result = true;
6193 PGresult *res;
6194
6195 switch (obj_type)
6196 {
6197 case EditableFunction:
6198
6199 /*
6200 * We have a function description, e.g. "x" or "x(int)". Issue a
6201 * query to retrieve the function's OID using a cast to regproc or
6202 * regprocedure (as appropriate).
6203 */
6204 appendPQExpBufferStr(query, "SELECT ");
6205 appendStringLiteralConn(query, desc, pset.db);
6206 appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
6207 strchr(desc, '(') ? "regprocedure" : "regproc");
6208 break;
6209
6210 case EditableView:
6211
6212 /*
6213 * Convert view name (possibly schema-qualified) to OID. Note:
6214 * this code doesn't check if the relation is actually a view.
6215 * We'll detect that in get_create_object_cmd().
6216 */
6217 appendPQExpBufferStr(query, "SELECT ");
6218 appendStringLiteralConn(query, desc, pset.db);
6219 appendPQExpBufferStr(query, "::pg_catalog.regclass::pg_catalog.oid");
6220 break;
6221 }
6222
6223 if (!echo_hidden_command(query->data))
6224 {
6225 destroyPQExpBuffer(query);
6226 return false;
6227 }
6228 res = PQexec(pset.db, query->data);
6229 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
6230 *obj_oid = atooid(PQgetvalue(res, 0, 0));
6231 else
6232 {
6234 result = false;
6235 }
6236
6237 PQclear(res);
6238 destroyPQExpBuffer(query);
6239
6240 return result;
6241}
6242
6243/*
6244 * Construct a "CREATE OR REPLACE ..." command that describes the specified
6245 * database object. If successful, the result is stored in buf.
6246 */
6247static bool
6250{
6251 bool result = true;
6253 PGresult *res;
6254
6255 switch (obj_type)
6256 {
6257 case EditableFunction:
6258 printfPQExpBuffer(query,
6259 "SELECT pg_catalog.pg_get_functiondef(%u)",
6260 oid);
6261 break;
6262
6263 case EditableView:
6264
6265 /*
6266 * pg_get_viewdef() just prints the query, so we must prepend
6267 * CREATE for ourselves. We must fully qualify the view name to
6268 * ensure the right view gets replaced. Also, check relation kind
6269 * to be sure it's a view.
6270 *
6271 * Starting with PG 9.4, views may have WITH [LOCAL|CASCADED]
6272 * CHECK OPTION. These are not part of the view definition
6273 * returned by pg_get_viewdef() and so need to be retrieved
6274 * separately. Materialized views (introduced in 9.3) may have
6275 * arbitrary storage parameter reloptions.
6276 */
6277 if (pset.sversion >= 90400)
6278 {
6279 printfPQExpBuffer(query,
6280 "SELECT nspname, relname, relkind, "
6281 "pg_catalog.pg_get_viewdef(c.oid, true), "
6282 "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
6283 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
6284 "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
6285 "FROM pg_catalog.pg_class c "
6286 "LEFT JOIN pg_catalog.pg_namespace n "
6287 "ON c.relnamespace = n.oid WHERE c.oid = %u",
6288 oid);
6289 }
6290 else
6291 {
6292 printfPQExpBuffer(query,
6293 "SELECT nspname, relname, relkind, "
6294 "pg_catalog.pg_get_viewdef(c.oid, true), "
6295 "c.reloptions AS reloptions, "
6296 "NULL AS checkoption "
6297 "FROM pg_catalog.pg_class c "
6298 "LEFT JOIN pg_catalog.pg_namespace n "
6299 "ON c.relnamespace = n.oid WHERE c.oid = %u",
6300 oid);
6301 }
6302 break;
6303 }
6304
6305 if (!echo_hidden_command(query->data))
6306 {
6307 destroyPQExpBuffer(query);
6308 return false;
6309 }
6310 res = PQexec(pset.db, query->data);
6311 if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
6312 {
6314 switch (obj_type)
6315 {
6316 case EditableFunction:
6317 appendPQExpBufferStr(buf, PQgetvalue(res, 0, 0));
6318 break;
6319
6320 case EditableView:
6321 {
6322 char *nspname = PQgetvalue(res, 0, 0);
6323 char *relname = PQgetvalue(res, 0, 1);
6324 char *relkind = PQgetvalue(res, 0, 2);
6325 char *viewdef = PQgetvalue(res, 0, 3);
6326 char *reloptions = PQgetvalue(res, 0, 4);
6327 char *checkoption = PQgetvalue(res, 0, 5);
6328
6329 /*
6330 * If the backend ever supports CREATE OR REPLACE
6331 * MATERIALIZED VIEW, allow that here; but as of today it
6332 * does not, so editing a matview definition in this way
6333 * is impossible.
6334 */
6335 switch (relkind[0])
6336 {
6337#ifdef NOT_USED
6338 case RELKIND_MATVIEW:
6339 appendPQExpBufferStr(buf, "CREATE OR REPLACE MATERIALIZED VIEW ");
6340 break;
6341#endif
6342 case RELKIND_VIEW:
6343 appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
6344 break;
6345 default:
6346 pg_log_error("\"%s.%s\" is not a view",
6347 nspname, relname);
6348 result = false;
6349 break;
6350 }
6351 appendPQExpBuffer(buf, "%s.", fmtId(nspname));
6353
6354 /* reloptions, if not an empty array "{}" */
6355 if (reloptions != NULL && strlen(reloptions) > 2)
6356 {
6357 appendPQExpBufferStr(buf, "\n WITH (");
6358 if (!appendReloptionsArray(buf, reloptions, "",
6359 pset.encoding,
6361 {
6362 pg_log_error("could not parse reloptions array");
6363 result = false;
6364 }
6366 }
6367
6368 /* View definition from pg_get_viewdef (a SELECT query) */
6369 appendPQExpBuffer(buf, " AS\n%s", viewdef);
6370
6371 /* Get rid of the semicolon that pg_get_viewdef appends */
6372 if (buf->len > 0 && buf->data[buf->len - 1] == ';')
6373 buf->data[--(buf->len)] = '\0';
6374
6375 /* WITH [LOCAL|CASCADED] CHECK OPTION */
6376 if (checkoption && checkoption[0] != '\0')
6377 appendPQExpBuffer(buf, "\n WITH %s CHECK OPTION",
6378 checkoption);
6379 }
6380 break;
6381 }
6382 /* Make sure result ends with a newline */
6383 if (buf->len > 0 && buf->data[buf->len - 1] != '\n')
6385 }
6386 else
6387 {
6389 result = false;
6390 }
6391
6392 PQclear(res);
6393 destroyPQExpBuffer(query);
6394
6395 return result;
6396}
6397
6398/*
6399 * If the given argument of \ef or \ev ends with a line number, delete the line
6400 * number from the argument string and return it as an integer. (We need
6401 * this kluge because we're too lazy to parse \ef's function or \ev's view
6402 * argument carefully --- we just slop it up in OT_WHOLE_LINE mode.)
6403 *
6404 * Returns -1 if no line number is present, 0 on error, or a positive value
6405 * on success.
6406 */
6407static int
6409{
6410 char *c;
6411 int lineno;
6412
6413 if (!obj || obj[0] == '\0')
6414 return -1;
6415
6416 c = obj + strlen(obj) - 1;
6417
6418 /*
6419 * This business of parsing backwards is dangerous as can be in a
6420 * multibyte environment: there is no reason to believe that we are
6421 * looking at the first byte of a character, nor are we necessarily
6422 * working in a "safe" encoding. Fortunately the bitpatterns we are
6423 * looking for are unlikely to occur as non-first bytes, but beware of
6424 * trying to expand the set of cases that can be recognized. We must
6425 * guard the <ctype.h> macros by using isascii() first, too.
6426 */
6427
6428 /* skip trailing whitespace */
6429 while (c > obj && isascii((unsigned char) *c) && isspace((unsigned char) *c))
6430 c--;
6431
6432 /* must have a digit as last non-space char */
6433 if (c == obj || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
6434 return -1;
6435
6436 /* find start of digit string */
6437 while (c > obj && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
6438 c--;
6439
6440 /* digits must be separated from object name by space or closing paren */
6441 /* notice also that we are not allowing an empty object name ... */
6442 if (c == obj || !isascii((unsigned char) *c) ||
6443 !(isspace((unsigned char) *c) || *c == ')'))
6444 return -1;
6445
6446 /* parse digit string */
6447 c++;
6448 lineno = atoi(c);
6449 if (lineno < 1)
6450 {
6451 pg_log_error("invalid line number: %s", c);
6452 return 0;
6453 }
6454
6455 /* strip digit string from object name */
6456 *c = '\0';
6457
6458 return lineno;
6459}
6460
6461/*
6462 * Count number of lines in the buffer.
6463 * This is used to test if pager is needed or not.
6464 */
6465static int
6467{
6468 int lineno = 0;
6469 const char *lines = buf->data;
6470
6471 while (*lines != '\0')
6472 {
6473 lineno++;
6474 /* find start of next line */
6475 lines = strchr(lines, '\n');
6476 if (!lines)
6477 break;
6478 lines++;
6479 }
6480
6481 return lineno;
6482}
6483
6484/*
6485 * Write text at *lines to output with line numbers.
6486 *
6487 * For functions, lineno "1" should correspond to the first line of the
6488 * function body; lines before that are unnumbered. We expect that
6489 * pg_get_functiondef() will emit that on a line beginning with "AS ",
6490 * "BEGIN ", or "RETURN ", and that there can be no such line before
6491 * the real start of the function body.
6492 *
6493 * Caution: this scribbles on *lines.
6494 */
6495static void
6496print_with_linenumbers(FILE *output, char *lines, bool is_func)
6497{
6498 bool in_header = is_func;
6499 int lineno = 0;
6500
6501 while (*lines != '\0')
6502 {
6503 char *eol;
6504
6505 if (in_header &&
6506 (strncmp(lines, "AS ", 3) == 0 ||
6507 strncmp(lines, "BEGIN ", 6) == 0 ||
6508 strncmp(lines, "RETURN ", 7) == 0))
6509 in_header = false;
6510
6511 /* increment lineno only for body's lines */
6512 if (!in_header)
6513 lineno++;
6514
6515 /* find and mark end of current line */
6516 eol = strchr(lines, '\n');
6517 if (eol != NULL)
6518 *eol = '\0';
6519
6520 /* show current line as appropriate */
6521 if (in_header)
6522 fprintf(output, " %s\n", lines);
6523 else
6524 fprintf(output, "%-7d %s\n", lineno, lines);
6525
6526 /* advance to next line, if any */
6527 if (eol == NULL)
6528 break;
6529 lines = ++eol;
6530 }
6531}
6532
6533/*
6534 * Report just the primary error; this is to avoid cluttering the output
6535 * with, for instance, a redisplay of the internally generated query
6536 */
6537static void
6539{
6540 PQExpBuffer msg;
6541 const char *fld;
6542
6543 msg = createPQExpBuffer();
6544
6546 if (fld)
6547 printfPQExpBuffer(msg, "%s: ", fld);
6548 else
6549 printfPQExpBuffer(msg, "ERROR: ");
6551 if (fld)
6552 appendPQExpBufferStr(msg, fld);
6553 else
6554 appendPQExpBufferStr(msg, "(not available)");
6555 appendPQExpBufferChar(msg, '\n');
6556
6557 pg_log_error("%s", msg->data);
6558
6559 destroyPQExpBuffer(msg);
6560}
void expand_tilde(char **filename)
Definition: common.c:2576
PGresult * PSQLexec(const char *query)
Definition: common.c:655
volatile sig_atomic_t sigint_interrupt_enabled
Definition: common.c:304
char * get_conninfo_value(const char *keyword)
Definition: common.c:2540
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:306
int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, int min_rows)
Definition: common.c:710
void SetShellResultVariables(int wait_result)
Definition: common.c:516
void NoticeProcessor(void *arg, const char *message)
Definition: common.c:279
void clean_extended_state(void)
Definition: common.c:2660
bool standard_strings(void)
Definition: common.c:2500
bool setQFout(const char *fname)
Definition: common.c:144
bool recognized_connection_string(const char *connstr)
Definition: common.c:2704
bool do_copy(const char *args)
Definition: copy.c:268
static Datum values[MAXATTR]
Definition: bootstrap.c:153
#define Min(x, y)
Definition: c.h:1008
#define PG_BINARY_R
Definition: c.h:1279
#define ngettext(s, p, n)
Definition: c.h:1185
#define pg_unreachable()
Definition: c.h:336
#define lengthof(array)
Definition: c.h:792
void ResetCancelConn(void)
Definition: cancel.c:107
static backslashResult exec_command_startpipeline(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3060
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2291
static backslashResult exec_command_getresults(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1929
static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch)
Definition: command.c:985
static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1643
int process_file(char *filename, bool use_relative_path)
Definition: command.c:4924
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2482
static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid, PQExpBuffer buf)
Definition: command.c:6248
static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2044
static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:3847
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1739
static char * pset_value_string(const char *param, printQueryOpt *popt)
Definition: command.c:5771
static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3139
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1875
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2024
static backslashResult exec_command_close_prepared(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:755
static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:3821
static bool set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
Definition: command.c:5034
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:5700
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch)
Definition: command.c:501
static void ignore_boolean_expression(PsqlScanState scan_state)
Definition: command.c:3720
static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
Definition: command.c:5915
static backslashResult exec_command_flushrequest(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1714
printQueryOpt * savePsetInfo(const printQueryOpt *popt)
Definition: command.c:5664
static backslashResult exec_command_bind(PsqlScanState scan_state, bool active_branch)
Definition: command.c:520
static const char * _unicode_linestyle2string(int linestyle)
Definition: command.c:5047
static PQExpBuffer gather_boolean_expression(PsqlScanState scan_state)
Definition: command.c:3673
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2542
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
Definition: command.c:3703
static backslashResult exec_command_bind_named(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:556
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool discard_on_quit, bool *edited)
Definition: command.c:4729
static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3521
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2104
static char * pset_quoted_string(const char *str)
Definition: command.c:5733
static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2150
static bool param_is_newly_set(const char *old_val, const char *new_val)
Definition: command.c:3893
static void ignore_slash_whole_line(PsqlScanState scan_state)
Definition: command.c:3773
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1673
static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf)
Definition: command.c:2765
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2459
static bool do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port)
Definition: command.c:3916
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, Oid *obj_oid)
Definition: command.c:6188
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1559
static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1021
static const char * pset_bool_string(bool val)
Definition: command.c:5726
static int count_lines_in_buf(PQExpBuffer buf)
Definition: command.c:6466
static bool echo_hidden_command(const char *query)
Definition: command.c:6156
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:3801
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3580
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
Definition: command.c:5077
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:691
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1988
static void printSSLInfo(void)
Definition: command.c:4501
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
Definition: command.c:1443
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:3233
static void ignore_slash_filepipe(PsqlScanState scan_state)
Definition: command.c:3753
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2876
static bool printPsetInfo(const char *param, printQueryOpt *popt)
Definition: command.c:5450
static const char * _align2string(enum printFormat in)
Definition: command.c:4991
static char * read_connect_arg(PsqlScanState scan_state)
Definition: command.c:3633
static char * restrict_key
Definition: command.c:200
static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2812
backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:231
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2618
static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:3365
static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2063
static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2331
static bool restricted
Definition: command.c:199
static bool editFile(const char *fname, int lineno)
Definition: command.c:4647
static backslashResult exec_command_sendpipeline(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2839
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3161
static backslashResult exec_command_restrict(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2783
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, bool show_verbose, bool show_system)
Definition: command.c:1305
void UnsyncVariables(void)
Definition: command.c:4625
static backslashResult exec_command_unrestrict(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:3193
static backslashResult exec_command_endpipeline(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3098
static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch)
Definition: command.c:605
static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1604
static void wait_until_connected(PGconn *conn)
Definition: command.c:4380
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:1347
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:2226
static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
Definition: command.c:788
static bool do_shell(const char *command)
Definition: command.c:5864
void SyncVariables(void)
Definition: command.c:4570
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch)
Definition: command.c:963
static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3602
static backslashResult exec_command_parse(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2508
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
Definition: command.c:997
static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2695
static void ignore_slash_options(PsqlScanState scan_state)
Definition: command.c:3736
static backslashResult exec_command_flush(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1695
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3117
static backslashResult exec_command(const char *cmd, PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:315
void connection_warnings(bool in_startup)
Definition: command.c:4442
static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch, const char *cmd, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:3263
static backslashResult exec_command_syncpipeline(PsqlScanState scan_state, bool active_branch)
Definition: command.c:3079
static void minimal_error_message(PGresult *res)
Definition: command.c:6538
static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, const char *cmd, bool is_func)
Definition: command.c:2977
static bool is_branching_command(const char *cmd)
Definition: command.c:3785
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch)
Definition: command.c:638
static void print_with_linenumbers(FILE *output, char *lines, bool is_func)
Definition: command.c:6496
static int strip_lineno_from_objdesc(char *obj)
Definition: command.c:6408
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1965
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:3543
static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2368
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1892
static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2751
EditableObjectType
Definition: command.c:51
@ EditableFunction
Definition: command.c:52
@ EditableView
Definition: command.c:53
#define DEFAULT_SHELL
Definition: command.c:5854
static backslashResult process_command_g_options(char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1800
static void printGSSInfo(void)
Definition: command.c:4529
static char * prompt_for_password(const char *username, bool *canceled)
Definition: command.c:3865
static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2929
@ 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
@ PSQL_CMD_SKIP_LINE
Definition: command.h:19
enum _backslashResult backslashResult
void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth)
Definition: conditional.c:173
ifState conditional_stack_peek(ConditionalStack cstack)
Definition: conditional.c:106
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:53
bool conditional_stack_pop(ConditionalStack cstack)
Definition: conditional.c:69
void conditional_stack_set_query_len(ConditionalStack cstack, int len)
Definition: conditional.c:151
int conditional_stack_get_query_len(ConditionalStack cstack)
Definition: conditional.c:162
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:140
int conditional_stack_get_paren_depth(ConditionalStack cstack)
Definition: conditional.c:184
bool conditional_stack_poke(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:118
@ IFSTATE_FALSE
Definition: conditional.h:34
@ IFSTATE_ELSE_TRUE
Definition: conditional.h:40
@ IFSTATE_IGNORED
Definition: conditional.h:37
@ IFSTATE_TRUE
Definition: conditional.h:32
@ IFSTATE_NONE
Definition: conditional.h:31
@ IFSTATE_ELSE_FALSE
Definition: conditional.h:42
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
bool listUserMappings(const char *pattern, bool verbose)
Definition: describe.c:6085
bool listTSConfigs(const char *pattern, bool verbose)
Definition: describe.c:5734
bool describeRoles(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:3746
bool listOpFamilyFunctions(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:7265
bool listPublications(const char *pattern)
Definition: describe.c:6430
bool listTSParsers(const char *pattern, bool verbose)
Definition: describe.c:5357
bool listExtensionContents(const char *pattern)
Definition: describe.c:6266
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:78
bool listForeignDataWrappers(const char *pattern, bool verbose)
Definition: describe.c:5938
bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
Definition: describe.c:4296
bool describeSubscriptions(const char *pattern, bool verbose)
Definition: describe.c:6802
bool describeRoleGrants(const char *pattern, bool showSystem)
Definition: describe.c:3962
bool listExtendedStats(const char *pattern)
Definition: describe.c:4893
bool describeTypes(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:639
bool listOperatorFamilies(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:7069
bool listForeignServers(const char *pattern, bool verbose)
Definition: describe.c:6009
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:1488
bool listDomains(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4582
bool listTSDictionaries(const char *pattern, bool verbose)
Definition: describe.c:5604
bool listDbRoleSettings(const char *pattern, const char *pattern2)
Definition: describe.c:3893
bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition: describe.c:295
bool listCollations(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:5113
bool listSchemas(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:5236
bool listExtensions(const char *pattern)
Definition: describe.c:6212
bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4041
bool listTSTemplates(const char *pattern, bool verbose)
Definition: describe.c:5669
bool describeTablespaces(const char *pattern, bool verbose)
Definition: describe.c:222
bool listCasts(const char *pattern, bool verbose)
Definition: describe.c:4989
bool listOpFamilyOperators(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:7158
bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition: describe.c:794
bool listOperatorClasses(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:6968
bool listForeignTables(const char *pattern, bool verbose)
Definition: describe.c:6140
bool describeConfigurationParameters(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4745
bool listEventTriggers(const char *pattern, bool verbose)
Definition: describe.c:4813
bool listDefaultACLs(const char *pattern)
Definition: describe.c:1214
bool listAllDbs(const char *pattern, bool verbose)
Definition: describe.c:946
bool listConversions(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4665
bool permissionsList(const char *pattern, bool showSystem)
Definition: describe.c:1050
bool describeAccessMethods(const char *pattern, bool verbose)
Definition: describe.c:148
bool listLargeObjects(bool verbose)
Definition: describe.c:7354
bool listLanguages(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4506
bool describePublications(const char *pattern)
Definition: describe.c:6568
bool objectDescription(const char *pattern, bool showSystem)
Definition: describe.c:1295
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define _(x)
Definition: elog.c:91
PGresult * PQchangePassword(PGconn *conn, const char *user, const char *passwd)
Definition: fe-auth.c:1531
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:7694
char * PQoptions(const PGconn *conn)
Definition: fe-connect.c:7633
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:7538
int PQfullProtocolVersion(const PGconn *conn)
Definition: fe-connect.c:7684
char * PQport(const PGconn *conn)
Definition: fe-connect.c:7607
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:7571
int PQconnectionUsedPassword(const PGconn *conn)
Definition: fe-connect.c:7772
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:7481
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2922
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:7525
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
Definition: fe-connect.c:6241
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7659
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:7757
int PQconnectionUsedGSSAPI(const PGconn *conn)
Definition: fe-connect.c:7783
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7641
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7794
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:872
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5316
PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
Definition: fe-connect.c:7856
char * PQhostaddr(const PGconn *conn)
Definition: fe-connect.c:7594
int PQbackendPID(const PGconn *conn)
Definition: fe-connect.c:7740
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:2207
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:7546
PGpipelineStatus PQpipelineStatus(const PGconn *conn)
Definition: fe-connect.c:7748
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
Definition: fe-connect.c:7844
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
Definition: fe-connect.c:7885
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7704
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:7730
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7802
void PQfreemem(void *ptr)
Definition: fe-exec.c:4048
char * PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
Definition: fe-exec.c:3451
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2278
int PQsocketPoll(int sock, int forRead, int forWrite, pg_usec_time_t end_time)
Definition: fe-misc.c:1141
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition: fe-misc.c:1235
int PQgssEncInUse(PGconn *conn)
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
int PQsslInUse(PGconn *conn)
Definition: fe-secure.c:103
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define pg_realloc_array(pointer, type, count)
Definition: fe_memutils.h:63
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:3191
void printTableCleanup(printTableContent *const content)
Definition: print.c:3372
void restore_sigpipe_trap(void)
Definition: print.c:3047
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition: print.c:3874
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:3078
void refresh_utf8format(const printTableOpt *opt)
Definition: print.c:3888
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3279
const printTextFormat pg_asciiformat
Definition: print.c:61
void ClosePager(FILE *pagerpipe)
Definition: print.c:3160
const printTextFormat pg_asciiformat_old
Definition: print.c:82
void disable_sigpipe_trap(void)
Definition: print.c:3024
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3636
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:3239
printTextFormat pg_utf8format
Definition: print.c:104
volatile sig_atomic_t cancel_pressed
Definition: print.c:48
@ PRINT_XHEADER_EXACT_WIDTH
Definition: print.h:78
@ PRINT_XHEADER_PAGE
Definition: print.h:76
@ PRINT_XHEADER_COLUMN
Definition: print.h:74
@ PRINT_XHEADER_FULL
Definition: print.h:72
unicode_linestyle
Definition: print.h:100
@ UNICODE_LINESTYLE_SINGLE
Definition: print.h:101
@ UNICODE_LINESTYLE_DOUBLE
Definition: print.h:102
printFormat
Definition: print.h:29
@ PRINT_LATEX_LONGTABLE
Definition: print.h:36
@ PRINT_CSV
Definition: print.h:33
@ PRINT_UNALIGNED
Definition: print.h:38
@ PRINT_ALIGNED
Definition: print.h:31
@ PRINT_TROFF_MS
Definition: print.h:37
@ PRINT_ASCIIDOC
Definition: print.h:32
@ PRINT_NOTHING
Definition: print.h:30
@ PRINT_LATEX
Definition: print.h:35
@ PRINT_HTML
Definition: print.h:34
@ PRINT_WRAPPED
Definition: print.h:39
#define newval
Assert(PointerIsAligned(start, uint64))
const char * str
#define free(a)
Definition: header.h:65
void helpVariables(unsigned short int pager)
Definition: help.c:369
void helpSQL(const char *topic, unsigned short int pager)
Definition: help.c:592
void slashUsage(unsigned short int pager)
Definition: help.c:148
void print_copyright(void)
Definition: help.c:754
FILE * output
long val
Definition: informix.c:689
static struct @171 value
static bool success
Definition: initdb.c:187
static char * username
Definition: initdb.c:153
bool printHistory(const char *fname, unsigned short int pager)
Definition: input.c:494
char * gets_fromFile(FILE *source)
Definition: input.c:186
return true
Definition: isn.c:130
int i
Definition: isn.c:77
static const JsonPathKeyword keywords[]
bool do_lo_export(const char *loid_arg, const char *filename_arg)
Definition: large_obj.c:142
bool do_lo_import(const char *filename_arg, const char *comment_arg)
Definition: large_obj.c:176
bool do_lo_unlink(const char *loid_arg)
Definition: large_obj.c:239
#define PQgetvalue
Definition: libpq-be-fe.h:253
#define PQclear
Definition: libpq-be-fe.h:245
#define PQresultErrorField
Definition: libpq-be-fe.h:249
#define PQresultStatus
Definition: libpq-be-fe.h:247
#define PQntuples
Definition: libpq-be-fe.h:251
@ CONNECTION_OK
Definition: libpq-fe.h:84
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:125
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:128
@ PQSHOW_CONTEXT_ALWAYS
Definition: libpq-fe.h:166
int64_t pg_usec_time_t
Definition: libpq-fe.h:238
@ PGRES_POLLING_ACTIVE
Definition: libpq-fe.h:119
@ PGRES_POLLING_OK
Definition: libpq-fe.h:118
@ PGRES_POLLING_READING
Definition: libpq-fe.h:116
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:117
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:115
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:187
@ PQERRORS_VERBOSE
Definition: libpq-fe.h:158
void pg_logging_config(int new_flags)
Definition: logging.c:166
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
#define PG_LOG_FLAG_TERSE
Definition: logging.h:86
#define pg_log_info(...)
Definition: logging.h:124
int MainLoop(FILE *source)
Definition: mainloop.c:33
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void pfree(void *pointer)
Definition: mcxt.c:1594
void * arg
NameData relname
Definition: pg_class.h:38
#define MAXPGPATH
#define FUNC_MAX_ARGS
const void size_t len
int32 encoding
Definition: pg_database.h:41
static int server_version
Definition: pg_dumpall.c:109
static char * filename
Definition: pg_dumpall.c:120
static char * user
Definition: pg_regress.c:119
static int port
Definition: pg_regress.c:115
static char * buf
Definition: pg_test_fsync.c:72
#define pg_encoding_to_char
Definition: pg_wchar.h:630
static int64 end_time
Definition: pgbench.c:176
#define pg_log_warning(...)
Definition: pgfnames.c:24
void join_path_components(char *ret_path, const char *head, const char *tail)
Definition: path.c:286
#define is_absolute_path(filename)
Definition: port.h:104
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void get_parent_directory(char *path)
Definition: path.c:1068
void canonicalize_path_enc(char *path, int encoding)
Definition: path.c:344
#define strerror
Definition: port.h:252
#define snprintf
Definition: port.h:239
#define printf(...)
Definition: port.h:245
bool has_drive_prefix(const char *path)
Definition: path.c:94
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
#define atooid(x)
Definition: postgres_ext.h:43
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:55
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:67
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
char * c
static int fd(const char *x, int i)
Definition: preproc-init.c:105
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
void psql_scan_reset(PsqlScanState state)
Definition: psqlscan.l:1275
void psql_scan_slash_command_end(PsqlScanState state)
void psql_scan_set_paren_depth(PsqlScanState state, int depth)
@ OT_NORMAL
Definition: psqlscanslash.h:17
@ OT_SQLID
Definition: psqlscanslash.h:18
@ OT_SQLIDHACK
Definition: psqlscanslash.h:19
@ OT_FILEPIPE
Definition: psqlscanslash.h:20
@ OT_WHOLE_LINE
Definition: psqlscanslash.h:21
char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)
int psql_scan_get_paren_depth(PsqlScanState state)
char * psql_scan_slash_command(PsqlScanState state)
static int before(chr x, chr y)
Definition: regc_locale.c:488
#define relpath(rlocator, forknum)
Definition: relpath.h:150
#define DEFAULT_EDITOR_LINENUMBER_ARG
Definition: settings.h:23
#define EXIT_SUCCESS
Definition: settings.h:193
#define EXIT_FAILURE
Definition: settings.h:197
@ PSQL_ECHO_HIDDEN_NOEXEC
Definition: settings.h:53
@ PSQL_ECHO_HIDDEN_OFF
Definition: settings.h:51
PsqlSettings pset
Definition: startup.c:32
@ PSQL_SEND_PIPELINE_SYNC
Definition: settings.h:78
@ PSQL_SEND_FLUSH
Definition: settings.h:81
@ PSQL_SEND_FLUSH_REQUEST
Definition: settings.h:82
@ PSQL_SEND_START_PIPELINE_MODE
Definition: settings.h:79
@ PSQL_SEND_EXTENDED_QUERY_PARAMS
Definition: settings.h:76
@ PSQL_SEND_EXTENDED_PARSE
Definition: settings.h:75
@ PSQL_SEND_END_PIPELINE_MODE
Definition: settings.h:80
@ PSQL_SEND_GET_RESULTS
Definition: settings.h:83
@ PSQL_SEND_EXTENDED_CLOSE
Definition: settings.h:74
@ PSQL_SEND_EXTENDED_QUERY_PREPARED
Definition: settings.h:77
#define DEFAULT_EDITOR
Definition: settings.h:22
void pg_usleep(long microsec)
Definition: signal.c:53
static long sleep_ms
Definition: slotsync.c:116
char * simple_prompt_extended(const char *prompt, bool echo, PromptInterruptContext *prompt_ctx)
Definition: sprompt.c:53
static void error(void)
Definition: sql-dyntest.c:147
static char * password
Definition: streamutil.c:51
char * dbname
Definition: streamutil.c:49
PGconn * conn
Definition: streamutil.c:52
int strtoint(const char *restrict str, char **restrict endptr, int base)
Definition: string.c:50
const char * fmtId(const char *rawid)
Definition: string_utils.c:248
void setFmtEncoding(int encoding)
Definition: string_utils.c:69
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:446
bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, const char *prefix, int encoding, bool std_strings)
Definition: string_utils.c:966
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:313
volatile sig_atomic_t * enabled
Definition: string.h:22
printQueryOpt popt
Definition: settings.h:112
double watch_interval
Definition: settings.h:175
char * gset_prefix
Definition: settings.h:117
VariableSpace vars
Definition: settings.h:151
char * inputfile
Definition: settings.h:143
PGVerbosity verbosity
Definition: settings.h:184
FILE * logfile
Definition: settings.h:149
char * stmtName
Definition: settings.h:124
PGconn * dead_conn
Definition: settings.h:158
char * ctv_args[4]
Definition: settings.h:133
PGresult * last_error_result
Definition: settings.h:110
char ** bind_params
Definition: settings.h:123
PGconn * db
Definition: settings.h:103
FILE * queryFout
Definition: settings.h:105
PSQL_SEND_MODE send_mode
Definition: settings.h:120
enum trivalue getPassword
Definition: settings.h:137
int requested_results
Definition: settings.h:129
PGContextVisibility show_context
Definition: settings.h:186
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:177
printQueryOpt * gsavepopt
Definition: settings.h:115
char * gfname
Definition: settings.h:114
bool cur_cmd_interactive
Definition: settings.h:140
bool gexec_flag
Definition: settings.h:119
bool crosstab_flag
Definition: settings.h:132
const char * progname
Definition: settings.h:142
bool gdesc_flag
Definition: settings.h:118
int bind_nparams
Definition: settings.h:122
const bool * translate_columns
Definition: print.h:192
printTableOpt topt
Definition: print.h:185
char * nullPrint
Definition: print.h:186
char * falsePrint
Definition: print.h:188
char * title
Definition: print.h:189
char ** footers
Definition: print.h:190
char * truePrint
Definition: print.h:187
unsigned short int expanded
Definition: print.h:114
unicode_linestyle unicode_border_linestyle
Definition: print.h:141
bool tuples_only
Definition: print.h:126
int columns
Definition: print.h:140
enum printFormat format
Definition: print.h:113
struct separator fieldSep
Definition: print.h:132
int expanded_header_exact_width
Definition: print.h:118
struct separator recordSep
Definition: print.h:133
printXheaderWidthType expanded_header_width_type
Definition: print.h:116
char csvFieldSep[2]
Definition: print.h:134
const printTextFormat * line_style
Definition: print.h:131
bool default_footer
Definition: print.h:129
int pager_min_lines
Definition: print.h:124
unsigned short int pager
Definition: print.h:122
char * tableAttr
Definition: print.h:137
bool numericLocale
Definition: print.h:135
int encoding
Definition: print.h:138
unsigned short int border
Definition: print.h:120
unicode_linestyle unicode_header_linestyle
Definition: print.h:143
unicode_linestyle unicode_column_linestyle
Definition: print.h:142
const char * name
Definition: print.h:84
bool separator_zero
Definition: print.h:108
char * separator
Definition: print.h:107
__time64_t st_mtime
Definition: win32_port.h:265
__int64 st_size
Definition: win32_port.h:263
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
Definition: timer.c:86
static void usage(const char *progname)
Definition: vacuumlo.c:414
trivalue
Definition: vacuumlo.c:35
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_DEFAULT
Definition: vacuumlo.c:36
@ TRI_NO
Definition: vacuumlo.c:37
void PrintVariables(VariableSpace space)
Definition: variables.c:256
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
Definition: variables.c:486
bool ParseVariableBool(const char *value, const char *name, bool *result)
Definition: variables.c:109
bool ParseVariableNum(const char *value, const char *name, int *result)
Definition: variables.c:158
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:281
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33
const char * name
#define SIGCHLD
Definition: win32_port.h:168
#define stat
Definition: win32_port.h:274
#define unsetenv(x)
Definition: win32_port.h:546
#define EINTR
Definition: win32_port.h:364
#define SIGALRM
Definition: win32_port.h:164
#define setenv(x, y, z)
Definition: win32_port.h:545
#define ITIMER_REAL
Definition: win32_port.h:180
int uid_t
Definition: win32_port.h:234