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