2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2022, PostgreSQL Global Development Group
6 * src/bin/psql/command.c
8 #include "postgres_fe.h"
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() */
24 #include <sys/stat.h> /* for stat() */
27 #include "catalog/pg_class_d.h"
30 #include "common/logging.h"
31 #include "common/string.h"
33 #include "crosstabview.h"
35 #include "fe_utils/cancel.h"
36 #include "fe_utils/print.h"
37 #include "fe_utils/string_utils.h"
40 #include "large_obj.h"
42 #include "libpq/pqcomm.h"
44 #include "portability/instr_time.h"
45 #include "pqexpbuffer.h"
46 #include "psqlscanslash.h"
48 #include "variables.h"
51 * Editable database object types.
53 typedef enum EditableObjectType
59 /* local function declarations */
60 static backslashResult
exec_command(const char *cmd
,
61 PsqlScanState scan_state
,
62 ConditionalStack cstack
,
63 PQExpBuffer query_buf
,
64 PQExpBuffer previous_buf
);
65 static backslashResult
exec_command_a(PsqlScanState scan_state
, bool active_branch
);
66 static backslashResult
exec_command_C(PsqlScanState scan_state
, bool active_branch
);
67 static backslashResult
exec_command_connect(PsqlScanState scan_state
, bool active_branch
);
68 static backslashResult
exec_command_cd(PsqlScanState scan_state
, bool active_branch
,
70 static backslashResult
exec_command_conninfo(PsqlScanState scan_state
, bool active_branch
);
71 static backslashResult
exec_command_copy(PsqlScanState scan_state
, bool active_branch
);
72 static backslashResult
exec_command_copyright(PsqlScanState scan_state
, bool active_branch
);
73 static backslashResult
exec_command_crosstabview(PsqlScanState scan_state
, bool active_branch
);
74 static backslashResult
exec_command_d(PsqlScanState scan_state
, bool active_branch
,
76 static bool exec_command_dfo(PsqlScanState scan_state
, const char *cmd
,
78 bool show_verbose
, bool show_system
);
79 static backslashResult
exec_command_edit(PsqlScanState scan_state
, bool active_branch
,
80 PQExpBuffer query_buf
, PQExpBuffer previous_buf
);
81 static backslashResult
exec_command_ef_ev(PsqlScanState scan_state
, bool active_branch
,
82 PQExpBuffer query_buf
, bool is_func
);
83 static backslashResult
exec_command_echo(PsqlScanState scan_state
, bool active_branch
,
85 static backslashResult
exec_command_elif(PsqlScanState scan_state
, ConditionalStack cstack
,
86 PQExpBuffer query_buf
);
87 static backslashResult
exec_command_else(PsqlScanState scan_state
, ConditionalStack cstack
,
88 PQExpBuffer query_buf
);
89 static backslashResult
exec_command_endif(PsqlScanState scan_state
, ConditionalStack cstack
,
90 PQExpBuffer query_buf
);
91 static backslashResult
exec_command_encoding(PsqlScanState scan_state
, bool active_branch
);
92 static backslashResult
exec_command_errverbose(PsqlScanState scan_state
, bool active_branch
);
93 static backslashResult
exec_command_f(PsqlScanState scan_state
, bool active_branch
);
94 static backslashResult
exec_command_g(PsqlScanState scan_state
, bool active_branch
,
96 static backslashResult
process_command_g_options(char *first_option
,
97 PsqlScanState scan_state
,
100 static backslashResult
exec_command_gdesc(PsqlScanState scan_state
, bool active_branch
);
101 static backslashResult
exec_command_getenv(PsqlScanState scan_state
, bool active_branch
,
103 static backslashResult
exec_command_gexec(PsqlScanState scan_state
, bool active_branch
);
104 static backslashResult
exec_command_gset(PsqlScanState scan_state
, bool active_branch
);
105 static backslashResult
exec_command_help(PsqlScanState scan_state
, bool active_branch
);
106 static backslashResult
exec_command_html(PsqlScanState scan_state
, bool active_branch
);
107 static backslashResult
exec_command_include(PsqlScanState scan_state
, bool active_branch
,
109 static backslashResult
exec_command_if(PsqlScanState scan_state
, ConditionalStack cstack
,
110 PQExpBuffer query_buf
);
111 static backslashResult
exec_command_list(PsqlScanState scan_state
, bool active_branch
,
113 static backslashResult
exec_command_lo(PsqlScanState scan_state
, bool active_branch
,
115 static backslashResult
exec_command_out(PsqlScanState scan_state
, bool active_branch
);
116 static backslashResult
exec_command_print(PsqlScanState scan_state
, bool active_branch
,
117 PQExpBuffer query_buf
, PQExpBuffer previous_buf
);
118 static backslashResult
exec_command_password(PsqlScanState scan_state
, bool active_branch
);
119 static backslashResult
exec_command_prompt(PsqlScanState scan_state
, bool active_branch
,
121 static backslashResult
exec_command_pset(PsqlScanState scan_state
, bool active_branch
);
122 static backslashResult
exec_command_quit(PsqlScanState scan_state
, bool active_branch
);
123 static backslashResult
exec_command_reset(PsqlScanState scan_state
, bool active_branch
,
124 PQExpBuffer query_buf
);
125 static backslashResult
exec_command_s(PsqlScanState scan_state
, bool active_branch
);
126 static backslashResult
exec_command_set(PsqlScanState scan_state
, bool active_branch
);
127 static backslashResult
exec_command_setenv(PsqlScanState scan_state
, bool active_branch
,
129 static backslashResult
exec_command_sf_sv(PsqlScanState scan_state
, bool active_branch
,
130 const char *cmd
, bool is_func
);
131 static backslashResult
exec_command_t(PsqlScanState scan_state
, bool active_branch
);
132 static backslashResult
exec_command_T(PsqlScanState scan_state
, bool active_branch
);
133 static backslashResult
exec_command_timing(PsqlScanState scan_state
, bool active_branch
);
134 static backslashResult
exec_command_unset(PsqlScanState scan_state
, bool active_branch
,
136 static backslashResult
exec_command_write(PsqlScanState scan_state
, bool active_branch
,
138 PQExpBuffer query_buf
, PQExpBuffer previous_buf
);
139 static backslashResult
exec_command_watch(PsqlScanState scan_state
, bool active_branch
,
140 PQExpBuffer query_buf
, PQExpBuffer previous_buf
);
141 static backslashResult
exec_command_x(PsqlScanState scan_state
, bool active_branch
);
142 static backslashResult
exec_command_z(PsqlScanState scan_state
, bool active_branch
);
143 static backslashResult
exec_command_shell_escape(PsqlScanState scan_state
, bool active_branch
);
144 static backslashResult
exec_command_slash_command_help(PsqlScanState scan_state
, bool active_branch
);
145 static char *read_connect_arg(PsqlScanState scan_state
);
146 static PQExpBuffer
gather_boolean_expression(PsqlScanState scan_state
);
147 static bool is_true_boolean_expression(PsqlScanState scan_state
, const char *name
);
148 static void ignore_boolean_expression(PsqlScanState scan_state
);
149 static void ignore_slash_options(PsqlScanState scan_state
);
150 static void ignore_slash_filepipe(PsqlScanState scan_state
);
151 static void ignore_slash_whole_line(PsqlScanState scan_state
);
152 static bool is_branching_command(const char *cmd
);
153 static void save_query_text_state(PsqlScanState scan_state
, ConditionalStack cstack
,
154 PQExpBuffer query_buf
);
155 static void discard_query_text(PsqlScanState scan_state
, ConditionalStack cstack
,
156 PQExpBuffer query_buf
);
157 static bool copy_previous_query(PQExpBuffer query_buf
, PQExpBuffer previous_buf
);
158 static bool do_connect(enum trivalue reuse_previous_specification
,
159 char *dbname
, char *user
, char *host
, char *port
);
160 static bool do_edit(const char *filename_arg
, PQExpBuffer query_buf
,
161 int lineno
, bool discard_on_quit
, bool *edited
);
162 static bool do_shell(const char *command
);
163 static bool do_watch(PQExpBuffer query_buf
, double sleep
);
164 static bool lookup_object_oid(EditableObjectType obj_type
, const char *desc
,
166 static bool get_create_object_cmd(EditableObjectType obj_type
, Oid oid
,
168 static int strip_lineno_from_objdesc(char *obj
);
169 static int count_lines_in_buf(PQExpBuffer buf
);
170 static void print_with_linenumbers(FILE *output
, char *lines
,
171 const char *header_keyword
);
172 static void minimal_error_message(PGresult
*res
);
174 static void printSSLInfo(void);
175 static void printGSSInfo(void);
176 static bool printPsetInfo(const char *param
, printQueryOpt
*popt
);
177 static char *pset_value_string(const char *param
, printQueryOpt
*popt
);
180 static void checkWin32Codepage(void);
188 * Handles all the different commands that start with '\'.
189 * Ordinarily called by MainLoop().
191 * scan_state is a lexer working state that is set to continue scanning
192 * just after the '\'. The lexer is advanced past the command and all
193 * arguments on return.
195 * cstack is the current \if stack state. This will be examined, and
196 * possibly modified by conditional commands.
198 * query_buf contains the query-so-far, which may be modified by
199 * execution of the backslash command (for example, \r clears it).
201 * previous_buf contains the query most recently sent to the server
202 * (empty if none yet). This should not be modified here, but some
203 * commands copy its content into query_buf.
205 * query_buf and previous_buf will be NULL when executing a "-c"
206 * command-line option.
208 * Returns a status code indicating what action is desired, see command.h.
213 HandleSlashCmds(PsqlScanState scan_state
,
214 ConditionalStack cstack
,
215 PQExpBuffer query_buf
,
216 PQExpBuffer previous_buf
)
218 backslashResult status
;
222 Assert(scan_state
!= NULL
);
223 Assert(cstack
!= NULL
);
225 /* Parse off the command name */
226 cmd
= psql_scan_slash_command(scan_state
);
228 /* And try to execute it */
229 status
= exec_command(cmd
, scan_state
, cstack
, query_buf
, previous_buf
);
231 if (status
== PSQL_CMD_UNKNOWN
)
233 pg_log_error("invalid command \\%s", cmd
);
234 if (pset
.cur_cmd_interactive
)
235 pg_log_error_hint("Try \\? for help.");
236 status
= PSQL_CMD_ERROR
;
239 if (status
!= PSQL_CMD_ERROR
)
242 * Eat any remaining arguments after a valid command. We want to
243 * suppress evaluation of backticks in this situation, so transiently
244 * push an inactive conditional-stack entry.
246 bool active_branch
= conditional_active(cstack
);
248 conditional_stack_push(cstack
, IFSTATE_IGNORED
);
249 while ((arg
= psql_scan_slash_option(scan_state
,
250 OT_NORMAL
, NULL
, false)))
253 pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd
, arg
);
256 conditional_stack_pop(cstack
);
260 /* silently throw away rest of line after an erroneous command */
261 while ((arg
= psql_scan_slash_option(scan_state
,
262 OT_WHOLE_LINE
, NULL
, false)))
266 /* if there is a trailing \\, swallow it */
267 psql_scan_slash_command_end(scan_state
);
271 /* some commands write to queryFout, so make sure output is sent */
272 fflush(pset
.queryFout
);
279 * Subroutine to actually try to execute a backslash command.
281 * The typical "success" result code is PSQL_CMD_SKIP_LINE, although some
282 * commands return something else. Failure result code is PSQL_CMD_ERROR,
283 * unless PSQL_CMD_UNKNOWN is more appropriate.
285 static backslashResult
286 exec_command(const char *cmd
,
287 PsqlScanState scan_state
,
288 ConditionalStack cstack
,
289 PQExpBuffer query_buf
,
290 PQExpBuffer previous_buf
)
292 backslashResult status
;
293 bool active_branch
= conditional_active(cstack
);
296 * In interactive mode, warn when we're ignoring a command within a false
297 * \if-branch. But we continue on, so as to parse and discard the right
298 * amount of parameter text. Each individual backslash command subroutine
299 * is responsible for doing nothing after discarding appropriate
300 * arguments, if !active_branch.
302 if (pset
.cur_cmd_interactive
&& !active_branch
&&
303 !is_branching_command(cmd
))
305 pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
309 if (strcmp(cmd
, "a") == 0)
310 status
= exec_command_a(scan_state
, active_branch
);
311 else if (strcmp(cmd
, "C") == 0)
312 status
= exec_command_C(scan_state
, active_branch
);
313 else if (strcmp(cmd
, "c") == 0 || strcmp(cmd
, "connect") == 0)
314 status
= exec_command_connect(scan_state
, active_branch
);
315 else if (strcmp(cmd
, "cd") == 0)
316 status
= exec_command_cd(scan_state
, active_branch
, cmd
);
317 else if (strcmp(cmd
, "conninfo") == 0)
318 status
= exec_command_conninfo(scan_state
, active_branch
);
319 else if (pg_strcasecmp(cmd
, "copy") == 0)
320 status
= exec_command_copy(scan_state
, active_branch
);
321 else if (strcmp(cmd
, "copyright") == 0)
322 status
= exec_command_copyright(scan_state
, active_branch
);
323 else if (strcmp(cmd
, "crosstabview") == 0)
324 status
= exec_command_crosstabview(scan_state
, active_branch
);
325 else if (cmd
[0] == 'd')
326 status
= exec_command_d(scan_state
, active_branch
, cmd
);
327 else if (strcmp(cmd
, "e") == 0 || strcmp(cmd
, "edit") == 0)
328 status
= exec_command_edit(scan_state
, active_branch
,
329 query_buf
, previous_buf
);
330 else if (strcmp(cmd
, "ef") == 0)
331 status
= exec_command_ef_ev(scan_state
, active_branch
, query_buf
, true);
332 else if (strcmp(cmd
, "ev") == 0)
333 status
= exec_command_ef_ev(scan_state
, active_branch
, query_buf
, false);
334 else if (strcmp(cmd
, "echo") == 0 || strcmp(cmd
, "qecho") == 0 ||
335 strcmp(cmd
, "warn") == 0)
336 status
= exec_command_echo(scan_state
, active_branch
, cmd
);
337 else if (strcmp(cmd
, "elif") == 0)
338 status
= exec_command_elif(scan_state
, cstack
, query_buf
);
339 else if (strcmp(cmd
, "else") == 0)
340 status
= exec_command_else(scan_state
, cstack
, query_buf
);
341 else if (strcmp(cmd
, "endif") == 0)
342 status
= exec_command_endif(scan_state
, cstack
, query_buf
);
343 else if (strcmp(cmd
, "encoding") == 0)
344 status
= exec_command_encoding(scan_state
, active_branch
);
345 else if (strcmp(cmd
, "errverbose") == 0)
346 status
= exec_command_errverbose(scan_state
, active_branch
);
347 else if (strcmp(cmd
, "f") == 0)
348 status
= exec_command_f(scan_state
, active_branch
);
349 else if (strcmp(cmd
, "g") == 0 || strcmp(cmd
, "gx") == 0)
350 status
= exec_command_g(scan_state
, active_branch
, cmd
);
351 else if (strcmp(cmd
, "gdesc") == 0)
352 status
= exec_command_gdesc(scan_state
, active_branch
);
353 else if (strcmp(cmd
, "getenv") == 0)
354 status
= exec_command_getenv(scan_state
, active_branch
, cmd
);
355 else if (strcmp(cmd
, "gexec") == 0)
356 status
= exec_command_gexec(scan_state
, active_branch
);
357 else if (strcmp(cmd
, "gset") == 0)
358 status
= exec_command_gset(scan_state
, active_branch
);
359 else if (strcmp(cmd
, "h") == 0 || strcmp(cmd
, "help") == 0)
360 status
= exec_command_help(scan_state
, active_branch
);
361 else if (strcmp(cmd
, "H") == 0 || strcmp(cmd
, "html") == 0)
362 status
= exec_command_html(scan_state
, active_branch
);
363 else if (strcmp(cmd
, "i") == 0 || strcmp(cmd
, "include") == 0 ||
364 strcmp(cmd
, "ir") == 0 || strcmp(cmd
, "include_relative") == 0)
365 status
= exec_command_include(scan_state
, active_branch
, cmd
);
366 else if (strcmp(cmd
, "if") == 0)
367 status
= exec_command_if(scan_state
, cstack
, query_buf
);
368 else if (strcmp(cmd
, "l") == 0 || strcmp(cmd
, "list") == 0 ||
369 strcmp(cmd
, "l+") == 0 || strcmp(cmd
, "list+") == 0)
370 status
= exec_command_list(scan_state
, active_branch
, cmd
);
371 else if (strncmp(cmd
, "lo_", 3) == 0)
372 status
= exec_command_lo(scan_state
, active_branch
, cmd
);
373 else if (strcmp(cmd
, "o") == 0 || strcmp(cmd
, "out") == 0)
374 status
= exec_command_out(scan_state
, active_branch
);
375 else if (strcmp(cmd
, "p") == 0 || strcmp(cmd
, "print") == 0)
376 status
= exec_command_print(scan_state
, active_branch
,
377 query_buf
, previous_buf
);
378 else if (strcmp(cmd
, "password") == 0)
379 status
= exec_command_password(scan_state
, active_branch
);
380 else if (strcmp(cmd
, "prompt") == 0)
381 status
= exec_command_prompt(scan_state
, active_branch
, cmd
);
382 else if (strcmp(cmd
, "pset") == 0)
383 status
= exec_command_pset(scan_state
, active_branch
);
384 else if (strcmp(cmd
, "q") == 0 || strcmp(cmd
, "quit") == 0)
385 status
= exec_command_quit(scan_state
, active_branch
);
386 else if (strcmp(cmd
, "r") == 0 || strcmp(cmd
, "reset") == 0)
387 status
= exec_command_reset(scan_state
, active_branch
, query_buf
);
388 else if (strcmp(cmd
, "s") == 0)
389 status
= exec_command_s(scan_state
, active_branch
);
390 else if (strcmp(cmd
, "set") == 0)
391 status
= exec_command_set(scan_state
, active_branch
);
392 else if (strcmp(cmd
, "setenv") == 0)
393 status
= exec_command_setenv(scan_state
, active_branch
, cmd
);
394 else if (strcmp(cmd
, "sf") == 0 || strcmp(cmd
, "sf+") == 0)
395 status
= exec_command_sf_sv(scan_state
, active_branch
, cmd
, true);
396 else if (strcmp(cmd
, "sv") == 0 || strcmp(cmd
, "sv+") == 0)
397 status
= exec_command_sf_sv(scan_state
, active_branch
, cmd
, false);
398 else if (strcmp(cmd
, "t") == 0)
399 status
= exec_command_t(scan_state
, active_branch
);
400 else if (strcmp(cmd
, "T") == 0)
401 status
= exec_command_T(scan_state
, active_branch
);
402 else if (strcmp(cmd
, "timing") == 0)
403 status
= exec_command_timing(scan_state
, active_branch
);
404 else if (strcmp(cmd
, "unset") == 0)
405 status
= exec_command_unset(scan_state
, active_branch
, cmd
);
406 else if (strcmp(cmd
, "w") == 0 || strcmp(cmd
, "write") == 0)
407 status
= exec_command_write(scan_state
, active_branch
, cmd
,
408 query_buf
, previous_buf
);
409 else if (strcmp(cmd
, "watch") == 0)
410 status
= exec_command_watch(scan_state
, active_branch
,
411 query_buf
, previous_buf
);
412 else if (strcmp(cmd
, "x") == 0)
413 status
= exec_command_x(scan_state
, active_branch
);
414 else if (strcmp(cmd
, "z") == 0)
415 status
= exec_command_z(scan_state
, active_branch
);
416 else if (strcmp(cmd
, "!") == 0)
417 status
= exec_command_shell_escape(scan_state
, active_branch
);
418 else if (strcmp(cmd
, "?") == 0)
419 status
= exec_command_slash_command_help(scan_state
, active_branch
);
421 status
= PSQL_CMD_UNKNOWN
;
424 * All the commands that return PSQL_CMD_SEND want to execute previous_buf
425 * if query_buf is empty. For convenience we implement that here, not in
426 * the individual command subroutines.
428 if (status
== PSQL_CMD_SEND
)
429 (void) copy_previous_query(query_buf
, previous_buf
);
436 * \a -- toggle field alignment
438 * This makes little sense but we keep it around.
440 static backslashResult
441 exec_command_a(PsqlScanState scan_state
, bool active_branch
)
447 if (pset
.popt
.topt
.format
!= PRINT_ALIGNED
)
448 success
= do_pset("format", "aligned", &pset
.popt
, pset
.quiet
);
450 success
= do_pset("format", "unaligned", &pset
.popt
, pset
.quiet
);
453 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
457 * \C -- override table title (formerly change HTML caption)
459 static backslashResult
460 exec_command_C(PsqlScanState scan_state
, bool active_branch
)
466 char *opt
= psql_scan_slash_option(scan_state
,
467 OT_NORMAL
, NULL
, true);
469 success
= do_pset("title", opt
, &pset
.popt
, pset
.quiet
);
473 ignore_slash_options(scan_state
);
475 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
479 * \c or \connect -- connect to database using the specified parameters.
481 * \c [-reuse-previous=BOOL] dbname user host port
483 * Specifying a parameter as '-' is equivalent to omitting it. Examples:
485 * \c - - hst Connect to current database on current port of
486 * host "hst" as current user.
487 * \c - usr - prt Connect to current database on port "prt" of current host
489 * \c dbs Connect to database "dbs" on current port of current host
492 static backslashResult
493 exec_command_connect(PsqlScanState scan_state
, bool active_branch
)
499 static const char prefix
[] = "-reuse-previous=";
504 enum trivalue reuse_previous
= TRI_DEFAULT
;
506 opt1
= read_connect_arg(scan_state
);
507 if (opt1
!= NULL
&& strncmp(opt1
, prefix
, sizeof(prefix
) - 1) == 0)
511 success
= ParseVariableBool(opt1
+ sizeof(prefix
) - 1,
516 reuse_previous
= on_off
? TRI_YES
: TRI_NO
;
518 opt1
= read_connect_arg(scan_state
);
522 if (success
) /* give up if reuse_previous was invalid */
524 opt2
= read_connect_arg(scan_state
);
525 opt3
= read_connect_arg(scan_state
);
526 opt4
= read_connect_arg(scan_state
);
528 success
= do_connect(reuse_previous
, opt1
, opt2
, opt3
, opt4
);
537 ignore_slash_options(scan_state
);
539 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
543 * \cd -- change directory
545 static backslashResult
546 exec_command_cd(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
552 char *opt
= psql_scan_slash_option(scan_state
,
553 OT_NORMAL
, NULL
, true);
561 /* This should match get_home_path() */
562 dir
= getenv("HOME");
563 if (dir
== NULL
|| dir
[0] == '\0')
565 uid_t user_id
= geteuid();
568 errno
= 0; /* clear errno before call */
569 pw
= getpwuid(user_id
);
574 pg_log_error("could not get home directory for user ID %ld: %s",
576 errno
? strerror(errno
) : _("user does not exist"));
583 * On Windows, 'cd' without arguments prints the current
584 * directory, so if someone wants to code this here instead...
593 pg_log_error("\\%s: could not change directory to \"%s\": %m",
601 ignore_slash_options(scan_state
);
603 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
607 * \conninfo -- display information about the current connection
609 static backslashResult
610 exec_command_conninfo(PsqlScanState scan_state
, bool active_branch
)
614 char *db
= PQdb(pset
.db
);
617 printf(_("You are currently not connected to a database.\n"));
620 char *host
= PQhost(pset
.db
);
621 char *hostaddr
= PQhostaddr(pset
.db
);
623 if (is_unixsock_path(host
))
625 /* hostaddr overrides host */
626 if (hostaddr
&& *hostaddr
)
627 printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
628 db
, PQuser(pset
.db
), hostaddr
, PQport(pset
.db
));
630 printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
631 db
, PQuser(pset
.db
), host
, PQport(pset
.db
));
635 if (hostaddr
&& *hostaddr
&& strcmp(host
, hostaddr
) != 0)
636 printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
637 db
, PQuser(pset
.db
), host
, hostaddr
, PQport(pset
.db
));
639 printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
640 db
, PQuser(pset
.db
), host
, PQport(pset
.db
));
647 return PSQL_CMD_SKIP_LINE
;
651 * \copy -- run a COPY command
653 static backslashResult
654 exec_command_copy(PsqlScanState scan_state
, bool active_branch
)
660 char *opt
= psql_scan_slash_option(scan_state
,
661 OT_WHOLE_LINE
, NULL
, false);
663 success
= do_copy(opt
);
667 ignore_slash_whole_line(scan_state
);
669 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
673 * \copyright -- print copyright notice
675 static backslashResult
676 exec_command_copyright(PsqlScanState scan_state
, bool active_branch
)
681 return PSQL_CMD_SKIP_LINE
;
685 * \crosstabview -- execute a query and display result in crosstab
687 static backslashResult
688 exec_command_crosstabview(PsqlScanState scan_state
, bool active_branch
)
690 backslashResult status
= PSQL_CMD_SKIP_LINE
;
696 for (i
= 0; i
< lengthof(pset
.ctv_args
); i
++)
697 pset
.ctv_args
[i
] = psql_scan_slash_option(scan_state
,
698 OT_NORMAL
, NULL
, true);
699 pset
.crosstab_flag
= true;
700 status
= PSQL_CMD_SEND
;
703 ignore_slash_options(scan_state
);
711 static backslashResult
712 exec_command_d(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
714 backslashResult status
= PSQL_CMD_SKIP_LINE
;
723 /* We don't do SQLID reduction on the pattern yet */
724 pattern
= psql_scan_slash_option(scan_state
,
725 OT_NORMAL
, NULL
, true);
727 show_verbose
= strchr(cmd
, '+') ? true : false;
728 show_system
= strchr(cmd
, 'S') ? true : false;
736 success
= describeTableDetails(pattern
, show_verbose
, show_system
);
738 /* standard listing of interesting things */
739 success
= listTables("tvmsE", NULL
, show_verbose
, show_system
);
743 char *pattern2
= NULL
;
745 if (pattern
&& cmd
[2] != '\0' && cmd
[2] != '+')
746 pattern2
= psql_scan_slash_option(scan_state
, OT_NORMAL
, NULL
, true);
752 success
= describeAccessMethods(pattern
, show_verbose
);
755 success
= listOperatorClasses(pattern
, pattern2
, show_verbose
);
758 success
= listOperatorFamilies(pattern
, pattern2
, show_verbose
);
761 success
= listOpFamilyOperators(pattern
, pattern2
, show_verbose
);
764 success
= listOpFamilyFunctions(pattern
, pattern2
, show_verbose
);
767 status
= PSQL_CMD_UNKNOWN
;
775 success
= describeAggregates(pattern
, show_verbose
, show_system
);
778 success
= describeTablespaces(pattern
, show_verbose
);
781 if (strncmp(cmd
, "dconfig", 7) == 0)
782 success
= describeConfigurationParameters(pattern
,
786 success
= listConversions(pattern
,
791 success
= listCasts(pattern
, show_verbose
);
794 if (strncmp(cmd
, "ddp", 3) == 0)
795 success
= listDefaultACLs(pattern
);
797 success
= objectDescription(pattern
, show_system
);
800 success
= listDomains(pattern
, show_verbose
, show_system
);
802 case 'f': /* function subsystem */
813 success
= exec_command_dfo(scan_state
, cmd
, pattern
,
814 show_verbose
, show_system
);
817 status
= PSQL_CMD_UNKNOWN
;
822 /* no longer distinct from \du */
823 success
= describeRoles(pattern
, show_verbose
, show_system
);
826 success
= listLargeObjects(show_verbose
);
829 success
= listLanguages(pattern
, show_verbose
, show_system
);
832 success
= listSchemas(pattern
, show_verbose
, show_system
);
835 success
= exec_command_dfo(scan_state
, cmd
, pattern
,
836 show_verbose
, show_system
);
839 success
= listCollations(pattern
, show_verbose
, show_system
);
842 success
= permissionsList(pattern
);
853 success
= listPartitionedTables(&cmd
[2], pattern
, show_verbose
);
856 status
= PSQL_CMD_UNKNOWN
;
862 success
= describeTypes(pattern
, show_verbose
, show_system
);
870 success
= listTables(&cmd
[1], pattern
, show_verbose
, show_system
);
873 if (cmd
[2] == 'd' && cmd
[3] == 's')
875 char *pattern2
= NULL
;
878 pattern2
= psql_scan_slash_option(scan_state
,
879 OT_NORMAL
, NULL
, true);
880 success
= listDbRoleSettings(pattern
, pattern2
);
885 status
= PSQL_CMD_UNKNOWN
;
892 success
= describePublications(pattern
);
894 success
= listPublications(pattern
);
897 success
= describeSubscriptions(pattern
, show_verbose
);
900 status
= PSQL_CMD_UNKNOWN
;
904 success
= describeRoles(pattern
, show_verbose
, show_system
);
906 case 'F': /* text search subsystem */
911 success
= listTSConfigs(pattern
, show_verbose
);
914 success
= listTSParsers(pattern
, show_verbose
);
917 success
= listTSDictionaries(pattern
, show_verbose
);
920 success
= listTSTemplates(pattern
, show_verbose
);
923 status
= PSQL_CMD_UNKNOWN
;
927 case 'e': /* SQL/MED subsystem */
931 success
= listForeignServers(pattern
, show_verbose
);
934 success
= listUserMappings(pattern
, show_verbose
);
937 success
= listForeignDataWrappers(pattern
, show_verbose
);
940 success
= listForeignTables(pattern
, show_verbose
);
943 status
= PSQL_CMD_UNKNOWN
;
947 case 'x': /* Extensions */
949 success
= listExtensionContents(pattern
);
951 success
= listExtensions(pattern
);
953 case 'X': /* Extended Statistics */
954 success
= listExtendedStats(pattern
);
956 case 'y': /* Event Triggers */
957 success
= listEventTriggers(pattern
, show_verbose
);
960 status
= PSQL_CMD_UNKNOWN
;
966 ignore_slash_options(scan_state
);
969 status
= PSQL_CMD_ERROR
;
974 /* \df and \do; messy enough to split out of exec_command_d */
976 exec_command_dfo(PsqlScanState scan_state
, const char *cmd
,
978 bool show_verbose
, bool show_system
)
981 char *arg_patterns
[FUNC_MAX_ARGS
];
982 int num_arg_patterns
= 0;
984 /* Collect argument-type patterns too */
985 if (pattern
) /* otherwise it was just \df or \do */
989 while ((ap
= psql_scan_slash_option(scan_state
,
990 OT_NORMAL
, NULL
, true)) != NULL
)
992 arg_patterns
[num_arg_patterns
++] = ap
;
993 if (num_arg_patterns
>= FUNC_MAX_ARGS
)
994 break; /* protect limited-size array */
999 success
= describeFunctions(&cmd
[2], pattern
,
1000 arg_patterns
, num_arg_patterns
,
1001 show_verbose
, show_system
);
1003 success
= describeOperators(pattern
,
1004 arg_patterns
, num_arg_patterns
,
1005 show_verbose
, show_system
);
1007 while (--num_arg_patterns
>= 0)
1008 free(arg_patterns
[num_arg_patterns
]);
1014 * \e or \edit -- edit the current query buffer, or edit a file and
1015 * make it the query buffer
1017 static backslashResult
1018 exec_command_edit(PsqlScanState scan_state
, bool active_branch
,
1019 PQExpBuffer query_buf
, PQExpBuffer previous_buf
)
1021 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1027 pg_log_error("no query buffer");
1028 status
= PSQL_CMD_ERROR
;
1036 fname
= psql_scan_slash_option(scan_state
,
1037 OT_NORMAL
, NULL
, true);
1040 /* try to get separate lineno arg */
1041 ln
= psql_scan_slash_option(scan_state
,
1042 OT_NORMAL
, NULL
, true);
1045 /* only one arg; maybe it is lineno not fname */
1047 strspn(fname
, "0123456789") == strlen(fname
))
1049 /* all digits, so assume it is lineno */
1060 pg_log_error("invalid line number: %s", ln
);
1061 status
= PSQL_CMD_ERROR
;
1064 if (status
!= PSQL_CMD_ERROR
)
1066 bool discard_on_quit
;
1068 expand_tilde(&fname
);
1071 canonicalize_path(fname
);
1072 /* Always clear buffer if the file isn't modified */
1073 discard_on_quit
= true;
1078 * If query_buf is empty, recall previous query for
1079 * editing. But in that case, the query buffer should be
1080 * emptied if editing doesn't modify the file.
1082 discard_on_quit
= copy_previous_query(query_buf
,
1086 if (do_edit(fname
, query_buf
, lineno
, discard_on_quit
, NULL
))
1087 status
= PSQL_CMD_NEWEDIT
;
1089 status
= PSQL_CMD_ERROR
;
1096 ignore_slash_options(scan_state
);
1102 * \ef/\ev -- edit the named function/view, or
1103 * present a blank CREATE FUNCTION/VIEW template if no argument is given
1105 static backslashResult
1106 exec_command_ef_ev(PsqlScanState scan_state
, bool active_branch
,
1107 PQExpBuffer query_buf
, bool is_func
)
1109 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1113 char *obj_desc
= psql_scan_slash_option(scan_state
,
1120 pg_log_error("no query buffer");
1121 status
= PSQL_CMD_ERROR
;
1125 Oid obj_oid
= InvalidOid
;
1126 EditableObjectType eot
= is_func
? EditableFunction
: EditableView
;
1128 lineno
= strip_lineno_from_objdesc(obj_desc
);
1131 /* error already reported */
1132 status
= PSQL_CMD_ERROR
;
1136 /* set up an empty command to fill in */
1137 resetPQExpBuffer(query_buf
);
1139 appendPQExpBufferStr(query_buf
,
1140 "CREATE FUNCTION ( )\n"
1143 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1147 appendPQExpBufferStr(query_buf
,
1150 " -- something...\n");
1152 else if (!lookup_object_oid(eot
, obj_desc
, &obj_oid
))
1154 /* error already reported */
1155 status
= PSQL_CMD_ERROR
;
1157 else if (!get_create_object_cmd(eot
, obj_oid
, query_buf
))
1159 /* error already reported */
1160 status
= PSQL_CMD_ERROR
;
1162 else if (is_func
&& lineno
> 0)
1165 * lineno "1" should correspond to the first line of the
1166 * function body. We expect that pg_get_functiondef() will
1167 * emit that on a line beginning with "AS ", and that there
1168 * can be no such line before the real start of the function
1169 * body. Increment lineno by the number of lines before that
1170 * line, so that it becomes relative to the first line of the
1171 * function definition.
1173 const char *lines
= query_buf
->data
;
1175 while (*lines
!= '\0')
1177 if (strncmp(lines
, "AS ", 3) == 0)
1180 /* find start of next line */
1181 lines
= strchr(lines
, '\n');
1189 if (status
!= PSQL_CMD_ERROR
)
1191 bool edited
= false;
1193 if (!do_edit(NULL
, query_buf
, lineno
, true, &edited
))
1194 status
= PSQL_CMD_ERROR
;
1196 puts(_("No changes"));
1198 status
= PSQL_CMD_NEWEDIT
;
1204 ignore_slash_whole_line(scan_state
);
1210 * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr
1212 static backslashResult
1213 exec_command_echo(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
1219 bool no_newline
= false;
1223 if (strcmp(cmd
, "qecho") == 0)
1224 fout
= pset
.queryFout
;
1225 else if (strcmp(cmd
, "warn") == 0)
1230 while ((value
= psql_scan_slash_option(scan_state
,
1231 OT_NORMAL
, "ed
, false)))
1233 if (first
&& !no_newline
&& !quoted
&& strcmp(value
, "-n") == 0)
1249 ignore_slash_options(scan_state
);
1251 return PSQL_CMD_SKIP_LINE
;
1255 * \encoding -- set/show client side encoding
1257 static backslashResult
1258 exec_command_encoding(PsqlScanState scan_state
, bool active_branch
)
1262 char *encoding
= psql_scan_slash_option(scan_state
,
1263 OT_NORMAL
, NULL
, false);
1268 puts(pg_encoding_to_char(pset
.encoding
));
1273 if (PQsetClientEncoding(pset
.db
, encoding
) == -1)
1274 pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding
);
1277 /* save encoding info into psql internal data */
1278 pset
.encoding
= PQclientEncoding(pset
.db
);
1279 pset
.popt
.topt
.encoding
= pset
.encoding
;
1280 SetVariable(pset
.vars
, "ENCODING",
1281 pg_encoding_to_char(pset
.encoding
));
1287 ignore_slash_options(scan_state
);
1289 return PSQL_CMD_SKIP_LINE
;
1293 * \errverbose -- display verbose message from last failed query
1295 static backslashResult
1296 exec_command_errverbose(PsqlScanState scan_state
, bool active_branch
)
1300 if (pset
.last_error_result
)
1304 msg
= PQresultVerboseErrorMessage(pset
.last_error_result
,
1306 PQSHOW_CONTEXT_ALWAYS
);
1309 pg_log_error("%s", msg
);
1313 puts(_("out of memory"));
1316 puts(_("There is no previous error."));
1319 return PSQL_CMD_SKIP_LINE
;
1323 * \f -- change field separator
1325 static backslashResult
1326 exec_command_f(PsqlScanState scan_state
, bool active_branch
)
1328 bool success
= true;
1332 char *fname
= psql_scan_slash_option(scan_state
,
1333 OT_NORMAL
, NULL
, false);
1335 success
= do_pset("fieldsep", fname
, &pset
.popt
, pset
.quiet
);
1339 ignore_slash_options(scan_state
);
1341 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1345 * \g [(pset-option[=pset-value] ...)] [filename/shell-command]
1346 * \gx [(pset-option[=pset-value] ...)] [filename/shell-command]
1348 * Send the current query. If pset options are specified, they are made
1349 * active just for this query. If a filename or pipe command is given,
1350 * the query output goes there. \gx implicitly sets "expanded=on" along
1351 * with any other pset options that are specified.
1353 static backslashResult
1354 exec_command_g(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
1356 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1360 * Because the option processing for this is fairly complicated, we do it
1361 * and then decide whether the branch is active.
1363 fname
= psql_scan_slash_option(scan_state
,
1364 OT_FILEPIPE
, NULL
, false);
1366 if (fname
&& fname
[0] == '(')
1368 /* Consume pset options through trailing ')' ... */
1369 status
= process_command_g_options(fname
+ 1, scan_state
,
1370 active_branch
, cmd
);
1372 /* ... and again attempt to scan the filename. */
1373 fname
= psql_scan_slash_option(scan_state
,
1374 OT_FILEPIPE
, NULL
, false);
1377 if (status
== PSQL_CMD_SKIP_LINE
&& active_branch
)
1383 expand_tilde(&fname
);
1384 pset
.gfname
= pg_strdup(fname
);
1386 if (strcmp(cmd
, "gx") == 0)
1388 /* save settings if not done already, then force expanded=on */
1389 if (pset
.gsavepopt
== NULL
)
1390 pset
.gsavepopt
= savePsetInfo(&pset
.popt
);
1391 pset
.popt
.topt
.expanded
= 1;
1393 status
= PSQL_CMD_SEND
;
1402 * Process parenthesized pset options for \g
1404 * Note: okay to modify first_option, but not to free it; caller does that
1406 static backslashResult
1407 process_command_g_options(char *first_option
, PsqlScanState scan_state
,
1408 bool active_branch
, const char *cmd
)
1410 bool success
= true;
1411 bool found_r_paren
= false;
1418 /* If not first time through, collect a new option */
1420 option
= first_option
;
1423 option
= psql_scan_slash_option(scan_state
,
1424 OT_NORMAL
, NULL
, false);
1429 pg_log_error("\\%s: missing right parenthesis", cmd
);
1436 /* Check for terminating right paren, and remove it from string */
1437 optlen
= strlen(option
);
1438 if (optlen
> 0 && option
[optlen
- 1] == ')')
1440 option
[--optlen
] = '\0';
1441 found_r_paren
= true;
1444 /* If there was anything besides parentheses, parse/execute it */
1447 /* We can have either "name" or "name=value" */
1448 char *valptr
= strchr(option
, '=');
1454 /* save settings if not done already, then apply option */
1455 if (pset
.gsavepopt
== NULL
)
1456 pset
.gsavepopt
= savePsetInfo(&pset
.popt
);
1457 success
&= do_pset(option
, valptr
, &pset
.popt
, true);
1461 /* Clean up after this option. We should not free first_option. */
1463 first_option
= NULL
;
1466 } while (!found_r_paren
);
1468 /* If we failed after already changing some options, undo side-effects */
1469 if (!success
&& active_branch
&& pset
.gsavepopt
)
1471 restorePsetInfo(&pset
.popt
, pset
.gsavepopt
);
1472 pset
.gsavepopt
= NULL
;
1475 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1479 * \gdesc -- describe query result
1481 static backslashResult
1482 exec_command_gdesc(PsqlScanState scan_state
, bool active_branch
)
1484 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1488 pset
.gdesc_flag
= true;
1489 status
= PSQL_CMD_SEND
;
1496 * \getenv -- set variable from environment variable
1498 static backslashResult
1499 exec_command_getenv(PsqlScanState scan_state
, bool active_branch
,
1502 bool success
= true;
1506 char *myvar
= psql_scan_slash_option(scan_state
,
1507 OT_NORMAL
, NULL
, false);
1508 char *envvar
= psql_scan_slash_option(scan_state
,
1509 OT_NORMAL
, NULL
, false);
1511 if (!myvar
|| !envvar
)
1513 pg_log_error("\\%s: missing required argument", cmd
);
1518 char *envval
= getenv(envvar
);
1520 if (envval
&& !SetVariable(pset
.vars
, myvar
, envval
))
1527 ignore_slash_options(scan_state
);
1529 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1533 * \gexec -- send query and execute each field of result
1535 static backslashResult
1536 exec_command_gexec(PsqlScanState scan_state
, bool active_branch
)
1538 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1542 pset
.gexec_flag
= true;
1543 status
= PSQL_CMD_SEND
;
1550 * \gset [prefix] -- send query and store result into variables
1552 static backslashResult
1553 exec_command_gset(PsqlScanState scan_state
, bool active_branch
)
1555 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1559 char *prefix
= psql_scan_slash_option(scan_state
,
1560 OT_NORMAL
, NULL
, false);
1563 pset
.gset_prefix
= prefix
;
1566 /* we must set a non-NULL prefix to trigger storing */
1567 pset
.gset_prefix
= pg_strdup("");
1569 /* gset_prefix is freed later */
1570 status
= PSQL_CMD_SEND
;
1573 ignore_slash_options(scan_state
);
1579 * \help [topic] -- print help about SQL commands
1581 static backslashResult
1582 exec_command_help(PsqlScanState scan_state
, bool active_branch
)
1586 char *opt
= psql_scan_slash_option(scan_state
,
1587 OT_WHOLE_LINE
, NULL
, false);
1590 /* strip any trailing spaces and semicolons */
1595 (isspace((unsigned char) opt
[len
- 1])
1596 || opt
[len
- 1] == ';'))
1600 helpSQL(opt
, pset
.popt
.topt
.pager
);
1604 ignore_slash_whole_line(scan_state
);
1606 return PSQL_CMD_SKIP_LINE
;
1610 * \H and \html -- toggle HTML formatting
1612 static backslashResult
1613 exec_command_html(PsqlScanState scan_state
, bool active_branch
)
1615 bool success
= true;
1619 if (pset
.popt
.topt
.format
!= PRINT_HTML
)
1620 success
= do_pset("format", "html", &pset
.popt
, pset
.quiet
);
1622 success
= do_pset("format", "aligned", &pset
.popt
, pset
.quiet
);
1625 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1629 * \i and \ir -- include a file
1631 static backslashResult
1632 exec_command_include(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
1634 bool success
= true;
1638 char *fname
= psql_scan_slash_option(scan_state
,
1639 OT_NORMAL
, NULL
, true);
1643 pg_log_error("\\%s: missing required argument", cmd
);
1648 bool include_relative
;
1650 include_relative
= (strcmp(cmd
, "ir") == 0
1651 || strcmp(cmd
, "include_relative") == 0);
1652 expand_tilde(&fname
);
1653 success
= (process_file(fname
, include_relative
) == EXIT_SUCCESS
);
1658 ignore_slash_options(scan_state
);
1660 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1664 * \if <expr> -- beginning of an \if..\endif block
1666 * <expr> is parsed as a boolean expression. Invalid expressions will emit a
1667 * warning and be treated as false. Statements that follow a false expression
1668 * will be parsed but ignored. Note that in the case where an \if statement
1669 * is itself within an inactive section of a block, then the entire inner
1670 * \if..\endif block will be parsed but ignored.
1672 static backslashResult
1673 exec_command_if(PsqlScanState scan_state
, ConditionalStack cstack
,
1674 PQExpBuffer query_buf
)
1676 if (conditional_active(cstack
))
1679 * First, push a new active stack entry; this ensures that the lexer
1680 * will perform variable substitution and backtick evaluation while
1681 * scanning the expression. (That should happen anyway, since we know
1682 * we're in an active outer branch, but let's be sure.)
1684 conditional_stack_push(cstack
, IFSTATE_TRUE
);
1686 /* Remember current query state in case we need to restore later */
1687 save_query_text_state(scan_state
, cstack
, query_buf
);
1690 * Evaluate the expression; if it's false, change to inactive state.
1692 if (!is_true_boolean_expression(scan_state
, "\\if expression"))
1693 conditional_stack_poke(cstack
, IFSTATE_FALSE
);
1698 * We're within an inactive outer branch, so this entire \if block
1699 * will be ignored. We don't want to evaluate the expression, so push
1700 * the "ignored" stack state before scanning it.
1702 conditional_stack_push(cstack
, IFSTATE_IGNORED
);
1704 /* Remember current query state in case we need to restore later */
1705 save_query_text_state(scan_state
, cstack
, query_buf
);
1707 ignore_boolean_expression(scan_state
);
1710 return PSQL_CMD_SKIP_LINE
;
1714 * \elif <expr> -- alternative branch in an \if..\endif block
1716 * <expr> is evaluated the same as in \if <expr>.
1718 static backslashResult
1719 exec_command_elif(PsqlScanState scan_state
, ConditionalStack cstack
,
1720 PQExpBuffer query_buf
)
1722 bool success
= true;
1724 switch (conditional_stack_peek(cstack
))
1729 * Just finished active branch of this \if block. Update saved
1730 * state so we will keep whatever data was put in query_buf by the
1733 save_query_text_state(scan_state
, cstack
, query_buf
);
1736 * Discard \elif expression and ignore the rest until \endif.
1737 * Switch state before reading expression to ensure proper lexer
1740 conditional_stack_poke(cstack
, IFSTATE_IGNORED
);
1741 ignore_boolean_expression(scan_state
);
1746 * Discard any query text added by the just-skipped branch.
1748 discard_query_text(scan_state
, cstack
, query_buf
);
1751 * Have not yet found a true expression in this \if block, so this
1752 * might be the first. We have to change state before examining
1753 * the expression, or the lexer won't do the right thing.
1755 conditional_stack_poke(cstack
, IFSTATE_TRUE
);
1756 if (!is_true_boolean_expression(scan_state
, "\\elif expression"))
1757 conditional_stack_poke(cstack
, IFSTATE_FALSE
);
1759 case IFSTATE_IGNORED
:
1762 * Discard any query text added by the just-skipped branch.
1764 discard_query_text(scan_state
, cstack
, query_buf
);
1767 * Skip expression and move on. Either the \if block already had
1768 * an active section, or whole block is being skipped.
1770 ignore_boolean_expression(scan_state
);
1772 case IFSTATE_ELSE_TRUE
:
1773 case IFSTATE_ELSE_FALSE
:
1774 pg_log_error("\\elif: cannot occur after \\else");
1778 /* no \if to elif from */
1779 pg_log_error("\\elif: no matching \\if");
1784 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1788 * \else -- final alternative in an \if..\endif block
1790 * Statements within an \else branch will only be executed if
1791 * all previous \if and \elif expressions evaluated to false
1792 * and the block was not itself being ignored.
1794 static backslashResult
1795 exec_command_else(PsqlScanState scan_state
, ConditionalStack cstack
,
1796 PQExpBuffer query_buf
)
1798 bool success
= true;
1800 switch (conditional_stack_peek(cstack
))
1805 * Just finished active branch of this \if block. Update saved
1806 * state so we will keep whatever data was put in query_buf by the
1809 save_query_text_state(scan_state
, cstack
, query_buf
);
1811 /* Now skip the \else branch */
1812 conditional_stack_poke(cstack
, IFSTATE_ELSE_FALSE
);
1817 * Discard any query text added by the just-skipped branch.
1819 discard_query_text(scan_state
, cstack
, query_buf
);
1822 * We've not found any true \if or \elif expression, so execute
1825 conditional_stack_poke(cstack
, IFSTATE_ELSE_TRUE
);
1827 case IFSTATE_IGNORED
:
1830 * Discard any query text added by the just-skipped branch.
1832 discard_query_text(scan_state
, cstack
, query_buf
);
1835 * Either we previously processed the active branch of this \if,
1836 * or the whole \if block is being skipped. Either way, skip the
1839 conditional_stack_poke(cstack
, IFSTATE_ELSE_FALSE
);
1841 case IFSTATE_ELSE_TRUE
:
1842 case IFSTATE_ELSE_FALSE
:
1843 pg_log_error("\\else: cannot occur after \\else");
1847 /* no \if to else from */
1848 pg_log_error("\\else: no matching \\if");
1853 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1857 * \endif -- ends an \if...\endif block
1859 static backslashResult
1860 exec_command_endif(PsqlScanState scan_state
, ConditionalStack cstack
,
1861 PQExpBuffer query_buf
)
1863 bool success
= true;
1865 switch (conditional_stack_peek(cstack
))
1868 case IFSTATE_ELSE_TRUE
:
1869 /* Close the \if block, keeping the query text */
1870 success
= conditional_stack_pop(cstack
);
1874 case IFSTATE_IGNORED
:
1875 case IFSTATE_ELSE_FALSE
:
1878 * Discard any query text added by the just-skipped branch.
1880 discard_query_text(scan_state
, cstack
, query_buf
);
1882 /* Close the \if block */
1883 success
= conditional_stack_pop(cstack
);
1888 pg_log_error("\\endif: no matching \\if");
1893 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1897 * \l -- list databases
1899 static backslashResult
1900 exec_command_list(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
1902 bool success
= true;
1909 pattern
= psql_scan_slash_option(scan_state
,
1910 OT_NORMAL
, NULL
, true);
1912 show_verbose
= strchr(cmd
, '+') ? true : false;
1914 success
= listAllDbs(pattern
, show_verbose
);
1919 ignore_slash_options(scan_state
);
1921 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
1925 * \lo_* -- large object operations
1927 static backslashResult
1928 exec_command_lo(PsqlScanState scan_state
, bool active_branch
, const char *cmd
)
1930 backslashResult status
= PSQL_CMD_SKIP_LINE
;
1931 bool success
= true;
1938 opt1
= psql_scan_slash_option(scan_state
,
1939 OT_NORMAL
, NULL
, true);
1940 opt2
= psql_scan_slash_option(scan_state
,
1941 OT_NORMAL
, NULL
, true);
1943 if (strcmp(cmd
+ 3, "export") == 0)
1947 pg_log_error("\\%s: missing required argument", cmd
);
1952 expand_tilde(&opt2
);
1953 success
= do_lo_export(opt1
, opt2
);
1957 else if (strcmp(cmd
+ 3, "import") == 0)
1961 pg_log_error("\\%s: missing required argument", cmd
);
1966 expand_tilde(&opt1
);
1967 success
= do_lo_import(opt1
, opt2
);
1971 else if (strcmp(cmd
+ 3, "list") == 0)
1972 success
= listLargeObjects(false);
1973 else if (strcmp(cmd
+ 3, "list+") == 0)
1974 success
= listLargeObjects(true);
1976 else if (strcmp(cmd
+ 3, "unlink") == 0)
1980 pg_log_error("\\%s: missing required argument", cmd
);
1984 success
= do_lo_unlink(opt1
);
1988 status
= PSQL_CMD_UNKNOWN
;
1994 ignore_slash_options(scan_state
);
1997 status
= PSQL_CMD_ERROR
;
2003 * \o -- set query output
2005 static backslashResult
2006 exec_command_out(PsqlScanState scan_state
, bool active_branch
)
2008 bool success
= true;
2012 char *fname
= psql_scan_slash_option(scan_state
,
2013 OT_FILEPIPE
, NULL
, true);
2015 expand_tilde(&fname
);
2016 success
= setQFout(fname
);
2020 ignore_slash_filepipe(scan_state
);
2022 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2026 * \p -- print the current query buffer
2028 static backslashResult
2029 exec_command_print(PsqlScanState scan_state
, bool active_branch
,
2030 PQExpBuffer query_buf
, PQExpBuffer previous_buf
)
2035 * We want to print the same thing \g would execute, but not to change
2036 * the query buffer state; so we can't use copy_previous_query().
2037 * Also, beware of possibility that buffer pointers are NULL.
2039 if (query_buf
&& query_buf
->len
> 0)
2040 puts(query_buf
->data
);
2041 else if (previous_buf
&& previous_buf
->len
> 0)
2042 puts(previous_buf
->data
);
2043 else if (!pset
.quiet
)
2044 puts(_("Query buffer is empty."));
2048 return PSQL_CMD_SKIP_LINE
;
2052 * \password -- set user password
2054 static backslashResult
2055 exec_command_password(PsqlScanState scan_state
, bool active_branch
)
2057 bool success
= true;
2061 char *user
= psql_scan_slash_option(scan_state
,
2062 OT_SQLID
, NULL
, true);
2065 PQExpBufferData buf
;
2066 PromptInterruptContext prompt_ctx
;
2070 /* By default, the command applies to CURRENT_USER */
2073 res
= PSQLexec("SELECT CURRENT_USER");
2075 return PSQL_CMD_ERROR
;
2077 user
= pg_strdup(PQgetvalue(res
, 0, 0));
2081 /* Set up to let SIGINT cancel simple_prompt_extended() */
2082 prompt_ctx
.jmpbuf
= sigint_interrupt_jmp
;
2083 prompt_ctx
.enabled
= &sigint_interrupt_enabled
;
2084 prompt_ctx
.canceled
= false;
2086 initPQExpBuffer(&buf
);
2087 printfPQExpBuffer(&buf
, _("Enter new password for user \"%s\": "), user
);
2089 pw1
= simple_prompt_extended(buf
.data
, false, &prompt_ctx
);
2090 if (!prompt_ctx
.canceled
)
2091 pw2
= simple_prompt_extended("Enter it again: ", false, &prompt_ctx
);
2093 if (prompt_ctx
.canceled
)
2098 else if (strcmp(pw1
, pw2
) != 0)
2100 pg_log_error("Passwords didn't match.");
2105 char *encrypted_password
;
2107 encrypted_password
= PQencryptPasswordConn(pset
.db
, pw1
, user
, NULL
);
2109 if (!encrypted_password
)
2111 pg_log_info("%s", PQerrorMessage(pset
.db
));
2118 printfPQExpBuffer(&buf
, "ALTER USER %s PASSWORD ",
2120 appendStringLiteralConn(&buf
, encrypted_password
, pset
.db
);
2121 res
= PSQLexec(buf
.data
);
2126 PQfreemem(encrypted_password
);
2133 termPQExpBuffer(&buf
);
2136 ignore_slash_options(scan_state
);
2138 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2142 * \prompt -- prompt and set variable
2144 static backslashResult
2145 exec_command_prompt(PsqlScanState scan_state
, bool active_branch
,
2148 bool success
= true;
2153 *prompt_text
= NULL
;
2157 arg1
= psql_scan_slash_option(scan_state
, OT_NORMAL
, NULL
, false);
2158 arg2
= psql_scan_slash_option(scan_state
, OT_NORMAL
, NULL
, false);
2162 pg_log_error("\\%s: missing required argument", cmd
);
2168 PromptInterruptContext prompt_ctx
;
2170 /* Set up to let SIGINT cancel simple_prompt_extended() */
2171 prompt_ctx
.jmpbuf
= sigint_interrupt_jmp
;
2172 prompt_ctx
.enabled
= &sigint_interrupt_enabled
;
2173 prompt_ctx
.canceled
= false;
2183 if (!pset
.inputfile
)
2185 result
= simple_prompt_extended(prompt_text
, true, &prompt_ctx
);
2191 fputs(prompt_text
, stdout
);
2194 result
= gets_fromFile(stdin
);
2197 pg_log_error("\\%s: could not read value for variable",
2203 if (prompt_ctx
.canceled
||
2204 (result
&& !SetVariable(pset
.vars
, opt
, result
)))
2213 ignore_slash_options(scan_state
);
2215 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2219 * \pset -- set printing parameters
2221 static backslashResult
2222 exec_command_pset(PsqlScanState scan_state
, bool active_branch
)
2224 bool success
= true;
2228 char *opt0
= psql_scan_slash_option(scan_state
,
2229 OT_NORMAL
, NULL
, false);
2230 char *opt1
= psql_scan_slash_option(scan_state
,
2231 OT_NORMAL
, NULL
, false);
2235 /* list all variables */
2238 static const char *const my_list
[] = {
2239 "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
2240 "fieldsep_zero", "footer", "format", "linestyle", "null",
2241 "numericlocale", "pager", "pager_min_lines",
2242 "recordsep", "recordsep_zero",
2243 "tableattr", "title", "tuples_only",
2244 "unicode_border_linestyle",
2245 "unicode_column_linestyle",
2246 "unicode_header_linestyle",
2251 for (i
= 0; my_list
[i
] != NULL
; i
++)
2253 char *val
= pset_value_string(my_list
[i
], &pset
.popt
);
2255 printf("%-24s %s\n", my_list
[i
], val
);
2262 success
= do_pset(opt0
, opt1
, &pset
.popt
, pset
.quiet
);
2268 ignore_slash_options(scan_state
);
2270 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2274 * \q or \quit -- exit psql
2276 static backslashResult
2277 exec_command_quit(PsqlScanState scan_state
, bool active_branch
)
2279 backslashResult status
= PSQL_CMD_SKIP_LINE
;
2282 status
= PSQL_CMD_TERMINATE
;
2288 * \r -- reset (clear) the query buffer
2290 static backslashResult
2291 exec_command_reset(PsqlScanState scan_state
, bool active_branch
,
2292 PQExpBuffer query_buf
)
2296 resetPQExpBuffer(query_buf
);
2297 psql_scan_reset(scan_state
);
2299 puts(_("Query buffer reset (cleared)."));
2302 return PSQL_CMD_SKIP_LINE
;
2306 * \s -- save history in a file or show it on the screen
2308 static backslashResult
2309 exec_command_s(PsqlScanState scan_state
, bool active_branch
)
2311 bool success
= true;
2315 char *fname
= psql_scan_slash_option(scan_state
,
2316 OT_NORMAL
, NULL
, true);
2318 expand_tilde(&fname
);
2319 success
= printHistory(fname
, pset
.popt
.topt
.pager
);
2320 if (success
&& !pset
.quiet
&& fname
)
2321 printf(_("Wrote history to file \"%s\".\n"), fname
);
2327 ignore_slash_options(scan_state
);
2329 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2333 * \set -- set variable
2335 static backslashResult
2336 exec_command_set(PsqlScanState scan_state
, bool active_branch
)
2338 bool success
= true;
2342 char *opt0
= psql_scan_slash_option(scan_state
,
2343 OT_NORMAL
, NULL
, false);
2347 /* list all variables */
2348 PrintVariables(pset
.vars
);
2354 * Set variable to the concatenation of the arguments.
2359 opt
= psql_scan_slash_option(scan_state
,
2360 OT_NORMAL
, NULL
, false);
2361 newval
= pg_strdup(opt
? opt
: "");
2364 while ((opt
= psql_scan_slash_option(scan_state
,
2365 OT_NORMAL
, NULL
, false)))
2367 newval
= pg_realloc(newval
, strlen(newval
) + strlen(opt
) + 1);
2368 strcat(newval
, opt
);
2372 if (!SetVariable(pset
.vars
, opt0
, newval
))
2380 ignore_slash_options(scan_state
);
2382 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2386 * \setenv -- set environment variable
2388 static backslashResult
2389 exec_command_setenv(PsqlScanState scan_state
, bool active_branch
,
2392 bool success
= true;
2396 char *envvar
= psql_scan_slash_option(scan_state
,
2397 OT_NORMAL
, NULL
, false);
2398 char *envval
= psql_scan_slash_option(scan_state
,
2399 OT_NORMAL
, NULL
, false);
2403 pg_log_error("\\%s: missing required argument", cmd
);
2406 else if (strchr(envvar
, '=') != NULL
)
2408 pg_log_error("\\%s: environment variable name must not contain \"=\"",
2414 /* No argument - unset the environment variable */
2420 /* Set variable to the value of the next argument */
2421 setenv(envvar
, envval
, 1);
2428 ignore_slash_options(scan_state
);
2430 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2434 * \sf/\sv -- show a function/view's source code
2436 static backslashResult
2437 exec_command_sf_sv(PsqlScanState scan_state
, bool active_branch
,
2438 const char *cmd
, bool is_func
)
2440 backslashResult status
= PSQL_CMD_SKIP_LINE
;
2444 bool show_linenumbers
= (strchr(cmd
, '+') != NULL
);
2447 Oid obj_oid
= InvalidOid
;
2448 EditableObjectType eot
= is_func
? EditableFunction
: EditableView
;
2450 buf
= createPQExpBuffer();
2451 obj_desc
= psql_scan_slash_option(scan_state
,
2452 OT_WHOLE_LINE
, NULL
, true);
2456 pg_log_error("function name is required");
2458 pg_log_error("view name is required");
2459 status
= PSQL_CMD_ERROR
;
2461 else if (!lookup_object_oid(eot
, obj_desc
, &obj_oid
))
2463 /* error already reported */
2464 status
= PSQL_CMD_ERROR
;
2466 else if (!get_create_object_cmd(eot
, obj_oid
, buf
))
2468 /* error already reported */
2469 status
= PSQL_CMD_ERROR
;
2476 /* Select output stream: stdout, pager, or file */
2477 if (pset
.queryFout
== stdout
)
2479 /* count lines in function to see if pager is needed */
2480 int lineno
= count_lines_in_buf(buf
);
2482 output
= PageOutput(lineno
, &(pset
.popt
.topt
));
2487 /* use previously set output file, without pager */
2488 output
= pset
.queryFout
;
2492 if (show_linenumbers
)
2495 * For functions, lineno "1" should correspond to the first
2496 * line of the function body. We expect that
2497 * pg_get_functiondef() will emit that on a line beginning
2498 * with "AS ", and that there can be no such line before the
2499 * real start of the function body.
2501 print_with_linenumbers(output
, buf
->data
,
2502 is_func
? "AS " : NULL
);
2506 /* just send the definition to output */
2507 fputs(buf
->data
, output
);
2515 destroyPQExpBuffer(buf
);
2518 ignore_slash_whole_line(scan_state
);
2524 * \t -- turn off table headers and row count
2526 static backslashResult
2527 exec_command_t(PsqlScanState scan_state
, bool active_branch
)
2529 bool success
= true;
2533 char *opt
= psql_scan_slash_option(scan_state
,
2534 OT_NORMAL
, NULL
, true);
2536 success
= do_pset("tuples_only", opt
, &pset
.popt
, pset
.quiet
);
2540 ignore_slash_options(scan_state
);
2542 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2546 * \T -- define html <table ...> attributes
2548 static backslashResult
2549 exec_command_T(PsqlScanState scan_state
, bool active_branch
)
2551 bool success
= true;
2555 char *value
= psql_scan_slash_option(scan_state
,
2556 OT_NORMAL
, NULL
, false);
2558 success
= do_pset("tableattr", value
, &pset
.popt
, pset
.quiet
);
2562 ignore_slash_options(scan_state
);
2564 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2568 * \timing -- enable/disable timing of queries
2570 static backslashResult
2571 exec_command_timing(PsqlScanState scan_state
, bool active_branch
)
2573 bool success
= true;
2577 char *opt
= psql_scan_slash_option(scan_state
,
2578 OT_NORMAL
, NULL
, false);
2581 success
= ParseVariableBool(opt
, "\\timing", &pset
.timing
);
2583 pset
.timing
= !pset
.timing
;
2587 puts(_("Timing is on."));
2589 puts(_("Timing is off."));
2594 ignore_slash_options(scan_state
);
2596 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2600 * \unset -- unset variable
2602 static backslashResult
2603 exec_command_unset(PsqlScanState scan_state
, bool active_branch
,
2606 bool success
= true;
2610 char *opt
= psql_scan_slash_option(scan_state
,
2611 OT_NORMAL
, NULL
, false);
2615 pg_log_error("\\%s: missing required argument", cmd
);
2618 else if (!SetVariable(pset
.vars
, opt
, NULL
))
2624 ignore_slash_options(scan_state
);
2626 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2630 * \w -- write query buffer to file
2632 static backslashResult
2633 exec_command_write(PsqlScanState scan_state
, bool active_branch
,
2635 PQExpBuffer query_buf
, PQExpBuffer previous_buf
)
2637 backslashResult status
= PSQL_CMD_SKIP_LINE
;
2641 char *fname
= psql_scan_slash_option(scan_state
,
2642 OT_FILEPIPE
, NULL
, true);
2644 bool is_pipe
= false;
2648 pg_log_error("no query buffer");
2649 status
= PSQL_CMD_ERROR
;
2655 pg_log_error("\\%s: missing required argument", cmd
);
2656 status
= PSQL_CMD_ERROR
;
2660 expand_tilde(&fname
);
2661 if (fname
[0] == '|')
2665 disable_sigpipe_trap();
2666 fd
= popen(&fname
[1], "w");
2670 canonicalize_path(fname
);
2671 fd
= fopen(fname
, "w");
2675 pg_log_error("%s: %m", fname
);
2676 status
= PSQL_CMD_ERROR
;
2686 * We want to print the same thing \g would execute, but not to
2687 * change the query buffer state; so we can't use
2688 * copy_previous_query(). Also, beware of possibility that buffer
2689 * pointers are NULL.
2691 if (query_buf
&& query_buf
->len
> 0)
2692 fprintf(fd
, "%s\n", query_buf
->data
);
2693 else if (previous_buf
&& previous_buf
->len
> 0)
2694 fprintf(fd
, "%s\n", previous_buf
->data
);
2697 result
= pclose(fd
);
2699 result
= fclose(fd
);
2703 pg_log_error("%s: %m", fname
);
2704 status
= PSQL_CMD_ERROR
;
2709 restore_sigpipe_trap();
2714 ignore_slash_filepipe(scan_state
);
2720 * \watch -- execute a query every N seconds
2722 static backslashResult
2723 exec_command_watch(PsqlScanState scan_state
, bool active_branch
,
2724 PQExpBuffer query_buf
, PQExpBuffer previous_buf
)
2726 bool success
= true;
2730 char *opt
= psql_scan_slash_option(scan_state
,
2731 OT_NORMAL
, NULL
, true);
2734 /* Convert optional sleep-length argument */
2737 sleep
= strtod(opt
, NULL
);
2743 /* If query_buf is empty, recall and execute previous query */
2744 (void) copy_previous_query(query_buf
, previous_buf
);
2746 success
= do_watch(query_buf
, sleep
);
2748 /* Reset the query buffer as though for \r */
2749 resetPQExpBuffer(query_buf
);
2750 psql_scan_reset(scan_state
);
2753 ignore_slash_options(scan_state
);
2755 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2759 * \x -- set or toggle expanded table representation
2761 static backslashResult
2762 exec_command_x(PsqlScanState scan_state
, bool active_branch
)
2764 bool success
= true;
2768 char *opt
= psql_scan_slash_option(scan_state
,
2769 OT_NORMAL
, NULL
, true);
2771 success
= do_pset("expanded", opt
, &pset
.popt
, pset
.quiet
);
2775 ignore_slash_options(scan_state
);
2777 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2781 * \z -- list table privileges (equivalent to \dp)
2783 static backslashResult
2784 exec_command_z(PsqlScanState scan_state
, bool active_branch
)
2786 bool success
= true;
2790 char *pattern
= psql_scan_slash_option(scan_state
,
2791 OT_NORMAL
, NULL
, true);
2793 success
= permissionsList(pattern
);
2797 ignore_slash_options(scan_state
);
2799 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2803 * \! -- execute shell command
2805 static backslashResult
2806 exec_command_shell_escape(PsqlScanState scan_state
, bool active_branch
)
2808 bool success
= true;
2812 char *opt
= psql_scan_slash_option(scan_state
,
2813 OT_WHOLE_LINE
, NULL
, false);
2815 success
= do_shell(opt
);
2819 ignore_slash_whole_line(scan_state
);
2821 return success
? PSQL_CMD_SKIP_LINE
: PSQL_CMD_ERROR
;
2825 * \? -- print help about backslash commands
2827 static backslashResult
2828 exec_command_slash_command_help(PsqlScanState scan_state
, bool active_branch
)
2832 char *opt0
= psql_scan_slash_option(scan_state
,
2833 OT_NORMAL
, NULL
, false);
2835 if (!opt0
|| strcmp(opt0
, "commands") == 0)
2836 slashUsage(pset
.popt
.topt
.pager
);
2837 else if (strcmp(opt0
, "options") == 0)
2838 usage(pset
.popt
.topt
.pager
);
2839 else if (strcmp(opt0
, "variables") == 0)
2840 helpVariables(pset
.popt
.topt
.pager
);
2842 slashUsage(pset
.popt
.topt
.pager
);
2847 ignore_slash_options(scan_state
);
2849 return PSQL_CMD_SKIP_LINE
;
2854 * Read and interpret an argument to the \connect slash command.
2856 * Returns a malloc'd string, or NULL if no/empty argument.
2859 read_connect_arg(PsqlScanState scan_state
)
2865 * Ideally we should treat the arguments as SQL identifiers. But for
2866 * backwards compatibility with 7.2 and older pg_dump files, we have to
2867 * take unquoted arguments verbatim (don't downcase them). For now,
2868 * double-quoted arguments may be stripped of double quotes (as if SQL
2869 * identifiers). By 7.4 or so, pg_dump files can be expected to
2870 * double-quote all mixed-case \connect arguments, and then we can get rid
2873 result
= psql_scan_slash_option(scan_state
, OT_SQLIDHACK
, "e
, true);
2881 if (*result
== '\0' || strcmp(result
, "-") == 0)
2891 * Read a boolean expression, return it as a PQExpBuffer string.
2893 * Note: anything more or less than one token will certainly fail to be
2894 * parsed by ParseVariableBool, so we don't worry about complaining here.
2895 * This routine's return data structure will need to be rethought anyway
2896 * to support likely future extensions such as "\if defined VARNAME".
2899 gather_boolean_expression(PsqlScanState scan_state
)
2901 PQExpBuffer exp_buf
= createPQExpBuffer();
2902 int num_options
= 0;
2905 /* collect all arguments for the conditional command into exp_buf */
2906 while ((value
= psql_scan_slash_option(scan_state
,
2907 OT_NORMAL
, NULL
, false)) != NULL
)
2909 /* add spaces between tokens */
2910 if (num_options
> 0)
2911 appendPQExpBufferChar(exp_buf
, ' ');
2912 appendPQExpBufferStr(exp_buf
, value
);
2921 * Read a boolean expression, return true if the expression
2922 * was a valid boolean expression that evaluated to true.
2923 * Otherwise return false.
2925 * Note: conditional stack's top state must be active, else lexer will
2926 * fail to expand variables and backticks.
2929 is_true_boolean_expression(PsqlScanState scan_state
, const char *name
)
2931 PQExpBuffer buf
= gather_boolean_expression(scan_state
);
2933 bool success
= ParseVariableBool(buf
->data
, name
, &value
);
2935 destroyPQExpBuffer(buf
);
2936 return success
&& value
;
2940 * Read a boolean expression, but do nothing with it.
2942 * Note: conditional stack's top state must be INACTIVE, else lexer will
2943 * expand variables and backticks, which we do not want here.
2946 ignore_boolean_expression(PsqlScanState scan_state
)
2948 PQExpBuffer buf
= gather_boolean_expression(scan_state
);
2950 destroyPQExpBuffer(buf
);
2954 * Read and discard "normal" slash command options.
2956 * This should be used for inactive-branch processing of any slash command
2957 * that eats one or more OT_NORMAL, OT_SQLID, or OT_SQLIDHACK parameters.
2958 * We don't need to worry about exactly how many it would eat, since the
2959 * cleanup logic in HandleSlashCmds would silently discard any extras anyway.
2962 ignore_slash_options(PsqlScanState scan_state
)
2966 while ((arg
= psql_scan_slash_option(scan_state
,
2967 OT_NORMAL
, NULL
, false)) != NULL
)
2972 * Read and discard FILEPIPE slash command argument.
2974 * This *MUST* be used for inactive-branch processing of any slash command
2975 * that takes an OT_FILEPIPE option. Otherwise we might consume a different
2976 * amount of option text in active and inactive cases.
2979 ignore_slash_filepipe(PsqlScanState scan_state
)
2981 char *arg
= psql_scan_slash_option(scan_state
,
2982 OT_FILEPIPE
, NULL
, false);
2988 * Read and discard whole-line slash command argument.
2990 * This *MUST* be used for inactive-branch processing of any slash command
2991 * that takes an OT_WHOLE_LINE option. Otherwise we might consume a different
2992 * amount of option text in active and inactive cases.
2995 ignore_slash_whole_line(PsqlScanState scan_state
)
2997 char *arg
= psql_scan_slash_option(scan_state
,
2998 OT_WHOLE_LINE
, NULL
, false);
3004 * Return true if the command given is a branching command.
3007 is_branching_command(const char *cmd
)
3009 return (strcmp(cmd
, "if") == 0 ||
3010 strcmp(cmd
, "elif") == 0 ||
3011 strcmp(cmd
, "else") == 0 ||
3012 strcmp(cmd
, "endif") == 0);
3016 * Prepare to possibly restore query buffer to its current state
3017 * (cf. discard_query_text).
3019 * We need to remember the length of the query buffer, and the lexer's
3020 * notion of the parenthesis nesting depth.
3023 save_query_text_state(PsqlScanState scan_state
, ConditionalStack cstack
,
3024 PQExpBuffer query_buf
)
3027 conditional_stack_set_query_len(cstack
, query_buf
->len
);
3028 conditional_stack_set_paren_depth(cstack
,
3029 psql_scan_get_paren_depth(scan_state
));
3033 * Discard any query text absorbed during an inactive conditional branch.
3035 * We must discard data that was appended to query_buf during an inactive
3036 * \if branch. We don't have to do anything there if there's no query_buf.
3038 * Also, reset the lexer state to the same paren depth there was before.
3039 * (The rest of its state doesn't need attention, since we could not be
3040 * inside a comment or literal or partial token.)
3043 discard_query_text(PsqlScanState scan_state
, ConditionalStack cstack
,
3044 PQExpBuffer query_buf
)
3048 int new_len
= conditional_stack_get_query_len(cstack
);
3050 Assert(new_len
>= 0 && new_len
<= query_buf
->len
);
3051 query_buf
->len
= new_len
;
3052 query_buf
->data
[new_len
] = '\0';
3054 psql_scan_set_paren_depth(scan_state
,
3055 conditional_stack_get_paren_depth(cstack
));
3059 * If query_buf is empty, copy previous_buf into it.
3061 * This is used by various slash commands for which re-execution of a
3062 * previous query is a common usage. For convenience, we allow the
3063 * case of query_buf == NULL (and do nothing).
3065 * Returns "true" if the previous query was copied into the query
3066 * buffer, else "false".
3069 copy_previous_query(PQExpBuffer query_buf
, PQExpBuffer previous_buf
)
3071 if (query_buf
&& query_buf
->len
== 0)
3073 appendPQExpBufferStr(query_buf
, previous_buf
->data
);
3080 * Ask the user for a password; 'username' is the username the
3081 * password is for, if one has been explicitly specified.
3082 * Returns a malloc'd string.
3083 * If 'canceled' is provided, *canceled will be set to true if the prompt
3084 * is canceled via SIGINT, and to false otherwise.
3087 prompt_for_password(const char *username
, bool *canceled
)
3090 PromptInterruptContext prompt_ctx
;
3092 /* Set up to let SIGINT cancel simple_prompt_extended() */
3093 prompt_ctx
.jmpbuf
= sigint_interrupt_jmp
;
3094 prompt_ctx
.enabled
= &sigint_interrupt_enabled
;
3095 prompt_ctx
.canceled
= false;
3097 if (username
== NULL
|| username
[0] == '\0')
3098 result
= simple_prompt_extended("Password: ", false, &prompt_ctx
);
3103 prompt_text
= psprintf(_("Password for user %s: "), username
);
3104 result
= simple_prompt_extended(prompt_text
, false, &prompt_ctx
);
3109 *canceled
= prompt_ctx
.canceled
;
3115 param_is_newly_set(const char *old_val
, const char *new_val
)
3117 if (new_val
== NULL
)
3120 if (old_val
== NULL
|| strcmp(old_val
, new_val
) != 0)
3127 * do_connect -- handler for \connect
3129 * Connects to a database with given parameters. If we are told to re-use
3130 * parameters, parameters from the previous connection are used where the
3131 * command's own options do not supply a value. Otherwise, libpq defaults
3134 * In interactive mode, if connection fails with the given parameters,
3135 * the old connection will be kept.
3138 do_connect(enum trivalue reuse_previous_specification
,
3139 char *dbname
, char *user
, char *host
, char *port
)
3141 PGconn
*o_conn
= pset
.db
,
3143 PQconninfoOption
*cinfo
;
3145 bool same_host
= false;
3146 char *password
= NULL
;
3147 char *client_encoding
;
3148 bool success
= true;
3149 bool keep_password
= true;
3150 bool has_connection_string
;
3151 bool reuse_previous
;
3153 has_connection_string
= dbname
?
3154 recognized_connection_string(dbname
) : false;
3156 /* Complain if we have additional arguments after a connection string. */
3157 if (has_connection_string
&& (user
|| host
|| port
))
3159 pg_log_error("Do not give user, host, or port separately when using a connection string");
3163 switch (reuse_previous_specification
)
3166 reuse_previous
= true;
3169 reuse_previous
= false;
3172 reuse_previous
= !has_connection_string
;
3177 * If we intend to re-use connection parameters, collect them out of the
3178 * old connection, then replace individual values as necessary. (We may
3179 * need to resort to looking at pset.dead_conn, if the connection died
3180 * previously.) Otherwise, obtain a PQconninfoOption array containing
3181 * libpq's defaults, and modify that. Note this function assumes that
3182 * PQconninfo, PQconndefaults, and PQconninfoParse will all produce arrays
3183 * containing the same options in the same order.
3188 cinfo
= PQconninfo(o_conn
);
3189 else if (pset
.dead_conn
)
3190 cinfo
= PQconninfo(pset
.dead_conn
);
3193 /* This is reachable after a non-interactive \connect failure */
3194 pg_log_error("No database connection exists to re-use parameters from");
3199 cinfo
= PQconndefaults();
3203 if (has_connection_string
)
3205 /* Parse the connstring and insert values into cinfo */
3206 PQconninfoOption
*replcinfo
;
3209 replcinfo
= PQconninfoParse(dbname
, &errmsg
);
3212 PQconninfoOption
*ci
;
3213 PQconninfoOption
*replci
;
3214 bool have_password
= false;
3216 for (ci
= cinfo
, replci
= replcinfo
;
3217 ci
->keyword
&& replci
->keyword
;
3220 Assert(strcmp(ci
->keyword
, replci
->keyword
) == 0);
3221 /* Insert value from connstring if one was provided */
3225 * We know that both val strings were allocated by
3226 * libpq, so the least messy way to avoid memory leaks
3229 char *swap
= replci
->val
;
3231 replci
->val
= ci
->val
;
3235 * Check whether connstring provides options affecting
3236 * password re-use. While any change in user, host,
3237 * hostaddr, or port causes us to ignore the old
3238 * connection's password, we don't force that for
3239 * dbname, since passwords aren't database-specific.
3241 if (replci
->val
== NULL
||
3242 strcmp(ci
->val
, replci
->val
) != 0)
3244 if (strcmp(replci
->keyword
, "user") == 0 ||
3245 strcmp(replci
->keyword
, "host") == 0 ||
3246 strcmp(replci
->keyword
, "hostaddr") == 0 ||
3247 strcmp(replci
->keyword
, "port") == 0)
3248 keep_password
= false;
3250 /* Also note whether connstring contains a password. */
3251 if (strcmp(replci
->keyword
, "password") == 0)
3252 have_password
= true;
3254 else if (!reuse_previous
)
3257 * When we have a connstring and are not re-using
3258 * parameters, swap *all* entries, even those not set
3259 * by the connstring. This avoids absorbing
3260 * environment-dependent defaults from the result of
3261 * PQconndefaults(). We don't want to do that because
3262 * they'd override service-file entries if the
3263 * connstring specifies a service parameter, whereas
3264 * the priority should be the other way around. libpq
3265 * can certainly recompute any defaults we don't pass
3266 * here. (In this situation, it's a bit wasteful to
3267 * have called PQconndefaults() at all, but not doing
3268 * so would require yet another major code path here.)
3270 replci
->val
= ci
->val
;
3274 Assert(ci
->keyword
== NULL
&& replci
->keyword
== NULL
);
3276 /* While here, determine how many option slots there are */
3277 nconnopts
= ci
- cinfo
;
3279 PQconninfoFree(replcinfo
);
3282 * If the connstring contains a password, tell the loop below
3283 * that we may use it, regardless of other settings (i.e.,
3284 * cinfo's password is no longer an "old" password).
3287 keep_password
= true;
3289 /* Don't let code below try to inject dbname into params. */
3294 /* PQconninfoParse failed */
3297 pg_log_error("%s", errmsg
);
3301 pg_log_error("out of memory");
3308 * If dbname isn't a connection string, then we'll inject it and
3309 * the other parameters into the keyword array below. (We can't
3310 * easily insert them into the cinfo array because of memory
3311 * management issues: PQconninfoFree would misbehave on Windows.)
3312 * However, to avoid dependencies on the order in which parameters
3313 * appear in the array, make a preliminary scan to set
3314 * keep_password and same_host correctly.
3316 * While any change in user, host, or port causes us to ignore the
3317 * old connection's password, we don't force that for dbname,
3318 * since passwords aren't database-specific.
3320 PQconninfoOption
*ci
;
3322 for (ci
= cinfo
; ci
->keyword
; ci
++)
3324 if (user
&& strcmp(ci
->keyword
, "user") == 0)
3326 if (!(ci
->val
&& strcmp(user
, ci
->val
) == 0))
3327 keep_password
= false;
3329 else if (host
&& strcmp(ci
->keyword
, "host") == 0)
3331 if (ci
->val
&& strcmp(host
, ci
->val
) == 0)
3334 keep_password
= false;
3336 else if (port
&& strcmp(ci
->keyword
, "port") == 0)
3338 if (!(ci
->val
&& strcmp(port
, ci
->val
) == 0))
3339 keep_password
= false;
3343 /* While here, determine how many option slots there are */
3344 nconnopts
= ci
- cinfo
;
3349 /* We failed to create the cinfo structure */
3350 pg_log_error("out of memory");
3355 * If the user asked to be prompted for a password, ask for one now. If
3356 * not, use the password from the old connection, provided the username
3357 * etc have not changed. Otherwise, try to connect without a password
3358 * first, and then ask for a password if needed.
3360 * XXX: this behavior leads to spurious connection attempts recorded in
3361 * the postmaster's log. But libpq offers no API that would let us obtain
3362 * a password and then continue with the first connection attempt.
3364 if (pset
.getPassword
== TRI_YES
&& success
)
3366 bool canceled
= false;
3369 * If a connstring or URI is provided, we don't know which username
3370 * will be used, since we haven't dug that out of the connstring.
3371 * Don't risk issuing a misleading prompt. As in startup.c, it does
3372 * not seem worth working harder, since this getPassword setting is
3373 * normally only used in noninteractive cases.
3375 password
= prompt_for_password(has_connection_string
? NULL
: user
,
3377 success
= !canceled
;
3381 * Consider whether to force client_encoding to "auto" (overriding
3382 * anything in the connection string). We do so if we have a terminal
3383 * connection and there is no PGCLIENTENCODING environment setting.
3385 if (pset
.notty
|| getenv("PGCLIENTENCODING"))
3386 client_encoding
= NULL
;
3388 client_encoding
= "auto";
3390 /* Loop till we have a connection or fail, which we might've already */
3393 const char **keywords
= pg_malloc((nconnopts
+ 1) * sizeof(*keywords
));
3394 const char **values
= pg_malloc((nconnopts
+ 1) * sizeof(*values
));
3396 PQconninfoOption
*ci
;
3399 * Copy non-default settings into the PQconnectdbParams parameter
3400 * arrays; but inject any values specified old-style, as well as any
3401 * interactively-obtained password, and a couple of fields we want to
3404 * If you change this code, see also the initial-connection code in
3407 for (ci
= cinfo
; ci
->keyword
; ci
++)
3409 keywords
[paramnum
] = ci
->keyword
;
3411 if (dbname
&& strcmp(ci
->keyword
, "dbname") == 0)
3412 values
[paramnum
++] = dbname
;
3413 else if (user
&& strcmp(ci
->keyword
, "user") == 0)
3414 values
[paramnum
++] = user
;
3415 else if (host
&& strcmp(ci
->keyword
, "host") == 0)
3416 values
[paramnum
++] = host
;
3417 else if (host
&& !same_host
&& strcmp(ci
->keyword
, "hostaddr") == 0)
3419 /* If we're changing the host value, drop any old hostaddr */
3420 values
[paramnum
++] = NULL
;
3422 else if (port
&& strcmp(ci
->keyword
, "port") == 0)
3423 values
[paramnum
++] = port
;
3424 /* If !keep_password, we unconditionally drop old password */
3425 else if ((password
|| !keep_password
) &&
3426 strcmp(ci
->keyword
, "password") == 0)
3427 values
[paramnum
++] = password
;
3428 else if (strcmp(ci
->keyword
, "fallback_application_name") == 0)
3429 values
[paramnum
++] = pset
.progname
;
3430 else if (client_encoding
&&
3431 strcmp(ci
->keyword
, "client_encoding") == 0)
3432 values
[paramnum
++] = client_encoding
;
3434 values
[paramnum
++] = ci
->val
;
3435 /* else, don't bother making libpq parse this keyword */
3437 /* add array terminator */
3438 keywords
[paramnum
] = NULL
;
3439 values
[paramnum
] = NULL
;
3441 /* Note we do not want libpq to re-expand the dbname parameter */
3442 n_conn
= PQconnectdbParams(keywords
, values
, false);
3447 if (PQstatus(n_conn
) == CONNECTION_OK
)
3451 * Connection attempt failed; either retry the connection attempt with
3452 * a new password, or give up.
3454 if (!password
&& PQconnectionNeedsPassword(n_conn
) && pset
.getPassword
!= TRI_NO
)
3456 bool canceled
= false;
3459 * Prompt for password using the username we actually connected
3460 * with --- it might've come out of "dbname" rather than "user".
3462 password
= prompt_for_password(PQuser(n_conn
), &canceled
);
3465 success
= !canceled
;
3470 * We'll report the error below ... unless n_conn is NULL, indicating
3471 * that libpq didn't have enough memory to make a PGconn.
3474 pg_log_error("out of memory");
3477 } /* end retry loop */
3479 /* Release locally allocated data, whether we succeeded or not */
3481 PQconninfoFree(cinfo
);
3486 * Failed to connect to the database. In interactive mode, keep the
3487 * previous connection to the DB; in scripting mode, close our
3488 * previous connection as well.
3490 if (pset
.cur_cmd_interactive
)
3494 pg_log_info("%s", PQerrorMessage(n_conn
));
3498 /* pset.db is left unmodified */
3500 pg_log_info("Previous connection kept");
3506 pg_log_error("\\connect: %s", PQerrorMessage(n_conn
));
3513 * Transition to having no connection.
3515 * Unlike CheckConnection(), we close the old connection
3516 * immediately to prevent its parameters from being re-used.
3517 * This is so that a script cannot accidentally reuse
3518 * parameters it did not expect to. Otherwise, the state
3519 * cleanup should be the same as in CheckConnection().
3527 /* On the same reasoning, release any dead_conn to prevent reuse */
3530 PQfinish(pset
.dead_conn
);
3531 pset
.dead_conn
= NULL
;
3539 * Replace the old connection with the new one, and update
3540 * connection-dependent variables. Keep the resynchronization logic in
3541 * sync with CheckConnection().
3543 PQsetNoticeProcessor(n_conn
, NoticeProcessor
, NULL
);
3546 connection_warnings(false); /* Must be after SyncVariables */
3548 /* Tell the user about the new connection */
3552 param_is_newly_set(PQhost(o_conn
), PQhost(pset
.db
)) ||
3553 param_is_newly_set(PQport(o_conn
), PQport(pset
.db
)))
3555 char *host
= PQhost(pset
.db
);
3556 char *hostaddr
= PQhostaddr(pset
.db
);
3558 if (is_unixsock_path(host
))
3560 /* hostaddr overrides host */
3561 if (hostaddr
&& *hostaddr
)
3562 printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
3563 PQdb(pset
.db
), PQuser(pset
.db
), hostaddr
, PQport(pset
.db
));
3565 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3566 PQdb(pset
.db
), PQuser(pset
.db
), host
, PQport(pset
.db
));
3570 if (hostaddr
&& *hostaddr
&& strcmp(host
, hostaddr
) != 0)
3571 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
3572 PQdb(pset
.db
), PQuser(pset
.db
), host
, hostaddr
, PQport(pset
.db
));
3574 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3575 PQdb(pset
.db
), PQuser(pset
.db
), host
, PQport(pset
.db
));
3579 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
3580 PQdb(pset
.db
), PQuser(pset
.db
));
3583 /* Drop no-longer-needed connection(s) */
3588 PQfinish(pset
.dead_conn
);
3589 pset
.dead_conn
= NULL
;
3597 connection_warnings(bool in_startup
)
3599 if (!pset
.quiet
&& !pset
.notty
)
3601 int client_ver
= PG_VERSION_NUM
;
3605 if (pset
.sversion
!= client_ver
)
3607 const char *server_version
;
3609 /* Try to get full text form, might include "devel" etc */
3610 server_version
= PQparameterStatus(pset
.db
, "server_version");
3611 /* Otherwise fall back on pset.sversion */
3612 if (!server_version
)
3614 formatPGVersionNumber(pset
.sversion
, true,
3615 sverbuf
, sizeof(sverbuf
));
3616 server_version
= sverbuf
;
3619 printf(_("%s (%s, server %s)\n"),
3620 pset
.progname
, PG_VERSION
, server_version
);
3622 /* For version match, only print psql banner on startup. */
3623 else if (in_startup
)
3624 printf("%s (%s)\n", pset
.progname
, PG_VERSION
);
3627 * Warn if server's major version is newer than ours, or if server
3628 * predates our support cutoff (currently 9.2).
3630 if (pset
.sversion
/ 100 > client_ver
/ 100 ||
3631 pset
.sversion
< 90200)
3632 printf(_("WARNING: %s major version %s, server major version %s.\n"
3633 " Some psql features might not work.\n"),
3635 formatPGVersionNumber(client_ver
, false,
3636 cverbuf
, sizeof(cverbuf
)),
3637 formatPGVersionNumber(pset
.sversion
, false,
3638 sverbuf
, sizeof(sverbuf
)));
3642 checkWin32Codepage();
3653 * Prints information about the current SSL connection, if SSL is in use
3658 const char *protocol
;
3660 const char *compression
;
3662 if (!PQsslInUse(pset
.db
))
3663 return; /* no SSL */
3665 protocol
= PQsslAttribute(pset
.db
, "protocol");
3666 cipher
= PQsslAttribute(pset
.db
, "cipher");
3667 compression
= PQsslAttribute(pset
.db
, "compression");
3669 printf(_("SSL connection (protocol: %s, cipher: %s, compression: %s)\n"),
3670 protocol
? protocol
: _("unknown"),
3671 cipher
? cipher
: _("unknown"),
3672 (compression
&& strcmp(compression
, "off") != 0) ? _("on") : _("off"));
3678 * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use
3683 if (!PQgssEncInUse(pset
.db
))
3684 return; /* no GSSAPI encryption in use */
3686 printf(_("GSSAPI-encrypted connection\n"));
3691 * checkWin32Codepage
3693 * Prints a warning when win32 console codepage differs from Windows codepage
3697 checkWin32Codepage(void)
3703 concp
= GetConsoleCP();
3706 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
3707 " 8-bit characters might not work correctly. See psql reference\n"
3708 " page \"Notes for Windows users\" for details.\n"),
3718 * Make psql's internal variables agree with connection state upon
3719 * establishing a new connection.
3725 const char *server_version
;
3727 /* get stuff from connection */
3728 pset
.encoding
= PQclientEncoding(pset
.db
);
3729 pset
.popt
.topt
.encoding
= pset
.encoding
;
3730 pset
.sversion
= PQserverVersion(pset
.db
);
3732 SetVariable(pset
.vars
, "DBNAME", PQdb(pset
.db
));
3733 SetVariable(pset
.vars
, "USER", PQuser(pset
.db
));
3734 SetVariable(pset
.vars
, "HOST", PQhost(pset
.db
));
3735 SetVariable(pset
.vars
, "PORT", PQport(pset
.db
));
3736 SetVariable(pset
.vars
, "ENCODING", pg_encoding_to_char(pset
.encoding
));
3738 /* this bit should match connection_warnings(): */
3739 /* Try to get full text form of version, might include "devel" etc */
3740 server_version
= PQparameterStatus(pset
.db
, "server_version");
3741 /* Otherwise fall back on pset.sversion */
3742 if (!server_version
)
3744 formatPGVersionNumber(pset
.sversion
, true, vbuf
, sizeof(vbuf
));
3745 server_version
= vbuf
;
3747 SetVariable(pset
.vars
, "SERVER_VERSION_NAME", server_version
);
3749 snprintf(vbuf
, sizeof(vbuf
), "%d", pset
.sversion
);
3750 SetVariable(pset
.vars
, "SERVER_VERSION_NUM", vbuf
);
3752 /* send stuff to it, too */
3753 PQsetErrorVerbosity(pset
.db
, pset
.verbosity
);
3754 PQsetErrorContextVisibility(pset
.db
, pset
.show_context
);
3760 * Clear variables that should be not be set when there is no connection.
3763 UnsyncVariables(void)
3765 SetVariable(pset
.vars
, "DBNAME", NULL
);
3766 SetVariable(pset
.vars
, "USER", NULL
);
3767 SetVariable(pset
.vars
, "HOST", NULL
);
3768 SetVariable(pset
.vars
, "PORT", NULL
);
3769 SetVariable(pset
.vars
, "ENCODING", NULL
);
3770 SetVariable(pset
.vars
, "SERVER_VERSION_NAME", NULL
);
3771 SetVariable(pset
.vars
, "SERVER_VERSION_NUM", NULL
);
3776 * helper for do_edit(): actually invoke the editor
3778 * Returns true on success, false if we failed to invoke the editor or
3779 * it returned nonzero status. (An error message is printed for failed-
3780 * to-invoke cases, but not if the editor returns nonzero status.)
3783 editFile(const char *fname
, int lineno
)
3785 const char *editorName
;
3786 const char *editor_lineno_arg
= NULL
;
3790 Assert(fname
!= NULL
);
3792 /* Find an editor to use */
3793 editorName
= getenv("PSQL_EDITOR");
3795 editorName
= getenv("EDITOR");
3797 editorName
= getenv("VISUAL");
3799 editorName
= DEFAULT_EDITOR
;
3801 /* Get line number argument, if we need it. */
3804 editor_lineno_arg
= getenv("PSQL_EDITOR_LINENUMBER_ARG");
3805 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
3806 if (!editor_lineno_arg
)
3807 editor_lineno_arg
= DEFAULT_EDITOR_LINENUMBER_ARG
;
3809 if (!editor_lineno_arg
)
3811 pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
3817 * On Unix the EDITOR value should *not* be quoted, since it might include
3818 * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
3819 * if necessary. But this policy is not very workable on Windows, due to
3820 * severe brain damage in their command shell plus the fact that standard
3821 * program paths include spaces.
3825 sys
= psprintf("exec %s %s%d '%s'",
3826 editorName
, editor_lineno_arg
, lineno
, fname
);
3828 sys
= psprintf("exec %s '%s'",
3832 sys
= psprintf("\"%s\" %s%d \"%s\"",
3833 editorName
, editor_lineno_arg
, lineno
, fname
);
3835 sys
= psprintf("\"%s\" \"%s\"",
3839 result
= system(sys
);
3841 pg_log_error("could not start editor \"%s\"", editorName
);
3842 else if (result
== 127)
3843 pg_log_error("could not start /bin/sh");
3851 * do_edit -- handler for \e
3853 * If you do not specify a filename, the current query buffer will be copied
3854 * into a temporary file.
3856 * After this function is done, the resulting file will be copied back into the
3857 * query buffer. As an exception to this, the query buffer will be emptied
3858 * if the file was not modified (or the editor failed) and the caller passes
3859 * "discard_on_quit" = true.
3861 * If "edited" isn't NULL, *edited will be set to true if the query buffer
3862 * is successfully replaced.
3865 do_edit(const char *filename_arg
, PQExpBuffer query_buf
,
3866 int lineno
, bool discard_on_quit
, bool *edited
)
3868 char fnametmp
[MAXPGPATH
];
3869 FILE *stream
= NULL
;
3877 fname
= filename_arg
;
3880 /* make a temp file to edit */
3882 const char *tmpdir
= getenv("TMPDIR");
3887 char tmpdir
[MAXPGPATH
];
3890 ret
= GetTempPath(MAXPGPATH
, tmpdir
);
3891 if (ret
== 0 || ret
> MAXPGPATH
)
3893 pg_log_error("could not locate temporary directory: %s",
3894 !ret
? strerror(errno
) : "");
3900 * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
3901 * current directory to the supplied path unless we use only
3902 * backslashes, so we do that.
3905 snprintf(fnametmp
, sizeof(fnametmp
), "%s%spsql.edit.%d.sql", tmpdir
,
3906 "/", (int) getpid());
3908 snprintf(fnametmp
, sizeof(fnametmp
), "%s%spsql.edit.%d.sql", tmpdir
,
3909 "" /* trailing separator already present */ , (int) getpid());
3912 fname
= (const char *) fnametmp
;
3914 fd
= open(fname
, O_WRONLY
| O_CREAT
| O_EXCL
, 0600);
3916 stream
= fdopen(fd
, "w");
3918 if (fd
== -1 || !stream
)
3920 pg_log_error("could not open temporary file \"%s\": %m", fname
);
3925 unsigned int ql
= query_buf
->len
;
3927 /* force newline-termination of what we send to editor */
3928 if (ql
> 0 && query_buf
->data
[ql
- 1] != '\n')
3930 appendPQExpBufferChar(query_buf
, '\n');
3934 if (fwrite(query_buf
->data
, 1, ql
, stream
) != ql
)
3936 pg_log_error("%s: %m", fname
);
3938 if (fclose(stream
) != 0)
3939 pg_log_error("%s: %m", fname
);
3941 if (remove(fname
) != 0)
3942 pg_log_error("%s: %m", fname
);
3946 else if (fclose(stream
) != 0)
3948 pg_log_error("%s: %m", fname
);
3949 if (remove(fname
) != 0)
3950 pg_log_error("%s: %m", fname
);
3958 * Try to set the file modification time of the temporary file
3959 * a few seconds in the past. Otherwise, the low granularity
3960 * (one second, or even worse on some filesystems) that we can
3961 * portably measure with stat(2) could lead us to not
3962 * recognize a modification, if the user typed very quickly.
3964 * This is a rather unlikely race condition, so don't error
3965 * out if the utime(2) call fails --- that would make the cure
3966 * worse than the disease.
3968 ut
.modtime
= ut
.actime
= time(NULL
) - 2;
3969 (void) utime(fname
, &ut
);
3974 if (!error
&& stat(fname
, &before
) != 0)
3976 pg_log_error("%s: %m", fname
);
3982 error
= !editFile(fname
, lineno
);
3984 if (!error
&& stat(fname
, &after
) != 0)
3986 pg_log_error("%s: %m", fname
);
3990 /* file was edited if the size or modification time has changed */
3992 (before
.st_size
!= after
.st_size
||
3993 before
.st_mtime
!= after
.st_mtime
))
3995 stream
= fopen(fname
, PG_BINARY_R
);
3998 pg_log_error("%s: %m", fname
);
4003 /* read file back into query_buf */
4006 resetPQExpBuffer(query_buf
);
4007 while (fgets(line
, sizeof(line
), stream
) != NULL
)
4008 appendPQExpBufferStr(query_buf
, line
);
4012 pg_log_error("%s: %m", fname
);
4014 resetPQExpBuffer(query_buf
);
4027 * If the file was not modified, and the caller requested it, discard
4030 if (discard_on_quit
)
4031 resetPQExpBuffer(query_buf
);
4034 /* remove temp file */
4037 if (remove(fname
) == -1)
4039 pg_log_error("%s: %m", fname
);
4052 * Reads commands from filename and passes them to the main processing loop.
4053 * Handler for \i and \ir, but can be used for other things as well. Returns
4054 * MainLoop() error code.
4056 * If use_relative_path is true and filename is not an absolute path, then open
4057 * the file from where the currently processed file (if any) is located.
4060 process_file(char *filename
, bool use_relative_path
)
4065 char relpath
[MAXPGPATH
];
4072 else if (strcmp(filename
, "-") != 0)
4074 canonicalize_path(filename
);
4077 * If we were asked to resolve the pathname relative to the location
4078 * of the currently executing script, and there is one, and this is a
4079 * relative pathname, then prepend all but the last pathname component
4080 * of the current script to this pathname.
4082 if (use_relative_path
&& pset
.inputfile
&&
4083 !is_absolute_path(filename
) && !has_drive_prefix(filename
))
4085 strlcpy(relpath
, pset
.inputfile
, sizeof(relpath
));
4086 get_parent_directory(relpath
);
4087 join_path_components(relpath
, relpath
, filename
);
4088 canonicalize_path(relpath
);
4093 fd
= fopen(filename
, PG_BINARY_R
);
4097 pg_log_error("%s: %m", filename
);
4098 return EXIT_FAILURE
;
4104 filename
= "<stdin>"; /* for future error messages */
4107 oldfilename
= pset
.inputfile
;
4108 pset
.inputfile
= filename
;
4110 pg_logging_config(pset
.inputfile
? 0 : PG_LOG_FLAG_TERSE
);
4112 result
= MainLoop(fd
);
4117 pset
.inputfile
= oldfilename
;
4119 pg_logging_config(pset
.inputfile
? 0 : PG_LOG_FLAG_TERSE
);
4127 _align2string(enum printFormat in
)
4137 case PRINT_ASCIIDOC
:
4149 case PRINT_LATEX_LONGTABLE
:
4150 return "latex-longtable";
4152 case PRINT_TROFF_MS
:
4155 case PRINT_UNALIGNED
:
4166 * Parse entered Unicode linestyle. If ok, update *linestyle and return
4167 * true, else return false.
4170 set_unicode_line_style(const char *value
, size_t vallen
,
4171 unicode_linestyle
*linestyle
)
4173 if (pg_strncasecmp("single", value
, vallen
) == 0)
4174 *linestyle
= UNICODE_LINESTYLE_SINGLE
;
4175 else if (pg_strncasecmp("double", value
, vallen
) == 0)
4176 *linestyle
= UNICODE_LINESTYLE_DOUBLE
;
4183 _unicode_linestyle2string(int linestyle
)
4187 case UNICODE_LINESTYLE_SINGLE
:
4190 case UNICODE_LINESTYLE_DOUBLE
:
4200 * Performs the assignment "param = value", where value could be NULL;
4201 * for some params that has an effect such as inversion, for others
4204 * Adjusts the state of the formatting options at *popt. (In practice that
4205 * is always pset.popt, but maybe someday it could be different.)
4207 * If successful and quiet is false, then invokes printPsetInfo() to report
4210 * Returns true if successful, else false (eg for invalid param or value).
4213 do_pset(const char *param
, const char *value
, printQueryOpt
*popt
, bool quiet
)
4217 Assert(param
!= NULL
);
4220 vallen
= strlen(value
);
4223 if (strcmp(param
, "format") == 0)
4225 static const struct fmt
4228 enum printFormat number
;
4231 /* remember to update error message below when adding more */
4232 {"aligned", PRINT_ALIGNED
},
4233 {"asciidoc", PRINT_ASCIIDOC
},
4235 {"html", PRINT_HTML
},
4236 {"latex", PRINT_LATEX
},
4237 {"troff-ms", PRINT_TROFF_MS
},
4238 {"unaligned", PRINT_UNALIGNED
},
4239 {"wrapped", PRINT_WRAPPED
}
4248 for (int i
= 0; i
< lengthof(formats
); i
++)
4250 if (pg_strncasecmp(formats
[i
].name
, value
, vallen
) == 0)
4256 pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
4258 formats
[match_pos
].name
, formats
[i
].name
);
4264 popt
->topt
.format
= formats
[match_pos
].number
;
4265 else if (pg_strncasecmp("latex-longtable", value
, vallen
) == 0)
4268 * We must treat latex-longtable specially because latex is a
4269 * prefix of it; if both were in the table above, we'd think
4270 * "latex" is ambiguous.
4272 popt
->topt
.format
= PRINT_LATEX_LONGTABLE
;
4276 pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
4282 /* set table line style */
4283 else if (strcmp(param
, "linestyle") == 0)
4287 else if (pg_strncasecmp("ascii", value
, vallen
) == 0)
4288 popt
->topt
.line_style
= &pg_asciiformat
;
4289 else if (pg_strncasecmp("old-ascii", value
, vallen
) == 0)
4290 popt
->topt
.line_style
= &pg_asciiformat_old
;
4291 else if (pg_strncasecmp("unicode", value
, vallen
) == 0)
4292 popt
->topt
.line_style
= &pg_utf8format
;
4295 pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
4300 /* set unicode border line style */
4301 else if (strcmp(param
, "unicode_border_linestyle") == 0)
4305 else if (set_unicode_line_style(value
, vallen
,
4306 &popt
->topt
.unicode_border_linestyle
))
4307 refresh_utf8format(&(popt
->topt
));
4310 pg_log_error("\\pset: allowed Unicode border line styles are single, double");
4315 /* set unicode column line style */
4316 else if (strcmp(param
, "unicode_column_linestyle") == 0)
4320 else if (set_unicode_line_style(value
, vallen
,
4321 &popt
->topt
.unicode_column_linestyle
))
4322 refresh_utf8format(&(popt
->topt
));
4325 pg_log_error("\\pset: allowed Unicode column line styles are single, double");
4330 /* set unicode header line style */
4331 else if (strcmp(param
, "unicode_header_linestyle") == 0)
4335 else if (set_unicode_line_style(value
, vallen
,
4336 &popt
->topt
.unicode_header_linestyle
))
4337 refresh_utf8format(&(popt
->topt
));
4340 pg_log_error("\\pset: allowed Unicode header line styles are single, double");
4345 /* set border style/width */
4346 else if (strcmp(param
, "border") == 0)
4349 popt
->topt
.border
= atoi(value
);
4352 /* set expanded/vertical mode */
4353 else if (strcmp(param
, "x") == 0 ||
4354 strcmp(param
, "expanded") == 0 ||
4355 strcmp(param
, "vertical") == 0)
4357 if (value
&& pg_strcasecmp(value
, "auto") == 0)
4358 popt
->topt
.expanded
= 2;
4363 if (ParseVariableBool(value
, NULL
, &on_off
))
4364 popt
->topt
.expanded
= on_off
? 1 : 0;
4367 PsqlVarEnumError(param
, value
, "on, off, auto");
4372 popt
->topt
.expanded
= !popt
->topt
.expanded
;
4375 /* header line width in expanded mode */
4376 else if (strcmp(param
, "xheader_width") == 0)
4380 else if (pg_strcasecmp(value
, "full") == 0)
4381 popt
->topt
.expanded_header_width_type
= PRINT_XHEADER_FULL
;
4382 else if (pg_strcasecmp(value
, "column") == 0)
4383 popt
->topt
.expanded_header_width_type
= PRINT_XHEADER_COLUMN
;
4384 else if (pg_strcasecmp(value
, "page") == 0)
4385 popt
->topt
.expanded_header_width_type
= PRINT_XHEADER_PAGE
;
4388 popt
->topt
.expanded_header_width_type
= PRINT_XHEADER_EXACT_WIDTH
;
4389 popt
->topt
.expanded_header_exact_width
= atoi(value
);
4390 if (popt
->topt
.expanded_header_exact_width
== 0)
4392 pg_log_error("\\pset: allowed xheader_width values are full (default), column, page, or a number specifying the exact width.");
4398 /* field separator for CSV format */
4399 else if (strcmp(param
, "csv_fieldsep") == 0)
4403 /* CSV separator has to be a one-byte character */
4404 if (strlen(value
) != 1)
4406 pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
4409 if (value
[0] == '"' || value
[0] == '\n' || value
[0] == '\r')
4411 pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
4414 popt
->topt
.csvFieldSep
[0] = value
[0];
4418 /* locale-aware numeric output */
4419 else if (strcmp(param
, "numericlocale") == 0)
4422 return ParseVariableBool(value
, param
, &popt
->topt
.numericLocale
);
4424 popt
->topt
.numericLocale
= !popt
->topt
.numericLocale
;
4428 else if (strcmp(param
, "null") == 0)
4432 free(popt
->nullPrint
);
4433 popt
->nullPrint
= pg_strdup(value
);
4437 /* field separator for unaligned text */
4438 else if (strcmp(param
, "fieldsep") == 0)
4442 free(popt
->topt
.fieldSep
.separator
);
4443 popt
->topt
.fieldSep
.separator
= pg_strdup(value
);
4444 popt
->topt
.fieldSep
.separator_zero
= false;
4448 else if (strcmp(param
, "fieldsep_zero") == 0)
4450 free(popt
->topt
.fieldSep
.separator
);
4451 popt
->topt
.fieldSep
.separator
= NULL
;
4452 popt
->topt
.fieldSep
.separator_zero
= true;
4455 /* record separator for unaligned text */
4456 else if (strcmp(param
, "recordsep") == 0)
4460 free(popt
->topt
.recordSep
.separator
);
4461 popt
->topt
.recordSep
.separator
= pg_strdup(value
);
4462 popt
->topt
.recordSep
.separator_zero
= false;
4466 else if (strcmp(param
, "recordsep_zero") == 0)
4468 free(popt
->topt
.recordSep
.separator
);
4469 popt
->topt
.recordSep
.separator
= NULL
;
4470 popt
->topt
.recordSep
.separator_zero
= true;
4473 /* toggle between full and tuples-only format */
4474 else if (strcmp(param
, "t") == 0 || strcmp(param
, "tuples_only") == 0)
4477 return ParseVariableBool(value
, param
, &popt
->topt
.tuples_only
);
4479 popt
->topt
.tuples_only
= !popt
->topt
.tuples_only
;
4482 /* set title override */
4483 else if (strcmp(param
, "C") == 0 || strcmp(param
, "title") == 0)
4489 popt
->title
= pg_strdup(value
);
4492 /* set HTML table tag options */
4493 else if (strcmp(param
, "T") == 0 || strcmp(param
, "tableattr") == 0)
4495 free(popt
->topt
.tableAttr
);
4497 popt
->topt
.tableAttr
= NULL
;
4499 popt
->topt
.tableAttr
= pg_strdup(value
);
4502 /* toggle use of pager */
4503 else if (strcmp(param
, "pager") == 0)
4505 if (value
&& pg_strcasecmp(value
, "always") == 0)
4506 popt
->topt
.pager
= 2;
4511 if (!ParseVariableBool(value
, NULL
, &on_off
))
4513 PsqlVarEnumError(param
, value
, "on, off, always");
4516 popt
->topt
.pager
= on_off
? 1 : 0;
4518 else if (popt
->topt
.pager
== 1)
4519 popt
->topt
.pager
= 0;
4521 popt
->topt
.pager
= 1;
4524 /* set minimum lines for pager use */
4525 else if (strcmp(param
, "pager_min_lines") == 0)
4528 popt
->topt
.pager_min_lines
= atoi(value
);
4531 /* disable "(x rows)" footer */
4532 else if (strcmp(param
, "footer") == 0)
4535 return ParseVariableBool(value
, param
, &popt
->topt
.default_footer
);
4537 popt
->topt
.default_footer
= !popt
->topt
.default_footer
;
4540 /* set border style/width */
4541 else if (strcmp(param
, "columns") == 0)
4544 popt
->topt
.columns
= atoi(value
);
4548 pg_log_error("\\pset: unknown option: %s", param
);
4553 printPsetInfo(param
, &pset
.popt
);
4559 * printPsetInfo: print the state of the "param" formatting parameter in popt.
4562 printPsetInfo(const char *param
, printQueryOpt
*popt
)
4564 Assert(param
!= NULL
);
4566 /* show border style/width */
4567 if (strcmp(param
, "border") == 0)
4568 printf(_("Border style is %d.\n"), popt
->topt
.border
);
4570 /* show the target width for the wrapped format */
4571 else if (strcmp(param
, "columns") == 0)
4573 if (!popt
->topt
.columns
)
4574 printf(_("Target width is unset.\n"));
4576 printf(_("Target width is %d.\n"), popt
->topt
.columns
);
4579 /* show expanded/vertical mode */
4580 else if (strcmp(param
, "x") == 0 || strcmp(param
, "expanded") == 0 || strcmp(param
, "vertical") == 0)
4582 if (popt
->topt
.expanded
== 1)
4583 printf(_("Expanded display is on.\n"));
4584 else if (popt
->topt
.expanded
== 2)
4585 printf(_("Expanded display is used automatically.\n"));
4587 printf(_("Expanded display is off.\n"));
4590 /* show xheader width value */
4591 else if (strcmp(param
, "xheader_width") == 0)
4593 if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_FULL
)
4594 printf(_("Expanded header width is 'full'.\n"));
4595 else if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_COLUMN
)
4596 printf(_("Expanded header width is 'column'.\n"));
4597 else if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_PAGE
)
4598 printf(_("Expanded header width is 'page'.\n"));
4599 else if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_EXACT_WIDTH
)
4600 printf(_("Expanded header width is %d.\n"), popt
->topt
.expanded_header_exact_width
);
4603 /* show field separator for CSV format */
4604 else if (strcmp(param
, "csv_fieldsep") == 0)
4606 printf(_("Field separator for CSV is \"%s\".\n"),
4607 popt
->topt
.csvFieldSep
);
4610 /* show field separator for unaligned text */
4611 else if (strcmp(param
, "fieldsep") == 0)
4613 if (popt
->topt
.fieldSep
.separator_zero
)
4614 printf(_("Field separator is zero byte.\n"));
4616 printf(_("Field separator is \"%s\".\n"),
4617 popt
->topt
.fieldSep
.separator
);
4620 else if (strcmp(param
, "fieldsep_zero") == 0)
4622 printf(_("Field separator is zero byte.\n"));
4625 /* show disable "(x rows)" footer */
4626 else if (strcmp(param
, "footer") == 0)
4628 if (popt
->topt
.default_footer
)
4629 printf(_("Default footer is on.\n"));
4631 printf(_("Default footer is off.\n"));
4635 else if (strcmp(param
, "format") == 0)
4637 printf(_("Output format is %s.\n"), _align2string(popt
->topt
.format
));
4640 /* show table line style */
4641 else if (strcmp(param
, "linestyle") == 0)
4643 printf(_("Line style is %s.\n"),
4644 get_line_style(&popt
->topt
)->name
);
4647 /* show null display */
4648 else if (strcmp(param
, "null") == 0)
4650 printf(_("Null display is \"%s\".\n"),
4651 popt
->nullPrint
? popt
->nullPrint
: "");
4654 /* show locale-aware numeric output */
4655 else if (strcmp(param
, "numericlocale") == 0)
4657 if (popt
->topt
.numericLocale
)
4658 printf(_("Locale-adjusted numeric output is on.\n"));
4660 printf(_("Locale-adjusted numeric output is off.\n"));
4663 /* show toggle use of pager */
4664 else if (strcmp(param
, "pager") == 0)
4666 if (popt
->topt
.pager
== 1)
4667 printf(_("Pager is used for long output.\n"));
4668 else if (popt
->topt
.pager
== 2)
4669 printf(_("Pager is always used.\n"));
4671 printf(_("Pager usage is off.\n"));
4674 /* show minimum lines for pager use */
4675 else if (strcmp(param
, "pager_min_lines") == 0)
4677 printf(ngettext("Pager won't be used for less than %d line.\n",
4678 "Pager won't be used for less than %d lines.\n",
4679 popt
->topt
.pager_min_lines
),
4680 popt
->topt
.pager_min_lines
);
4683 /* show record separator for unaligned text */
4684 else if (strcmp(param
, "recordsep") == 0)
4686 if (popt
->topt
.recordSep
.separator_zero
)
4687 printf(_("Record separator is zero byte.\n"));
4688 else if (strcmp(popt
->topt
.recordSep
.separator
, "\n") == 0)
4689 printf(_("Record separator is <newline>.\n"));
4691 printf(_("Record separator is \"%s\".\n"),
4692 popt
->topt
.recordSep
.separator
);
4695 else if (strcmp(param
, "recordsep_zero") == 0)
4697 printf(_("Record separator is zero byte.\n"));
4700 /* show HTML table tag options */
4701 else if (strcmp(param
, "T") == 0 || strcmp(param
, "tableattr") == 0)
4703 if (popt
->topt
.tableAttr
)
4704 printf(_("Table attributes are \"%s\".\n"),
4705 popt
->topt
.tableAttr
);
4707 printf(_("Table attributes unset.\n"));
4710 /* show title override */
4711 else if (strcmp(param
, "C") == 0 || strcmp(param
, "title") == 0)
4714 printf(_("Title is \"%s\".\n"), popt
->title
);
4716 printf(_("Title is unset.\n"));
4719 /* show toggle between full and tuples-only format */
4720 else if (strcmp(param
, "t") == 0 || strcmp(param
, "tuples_only") == 0)
4722 if (popt
->topt
.tuples_only
)
4723 printf(_("Tuples only is on.\n"));
4725 printf(_("Tuples only is off.\n"));
4728 /* Unicode style formatting */
4729 else if (strcmp(param
, "unicode_border_linestyle") == 0)
4731 printf(_("Unicode border line style is \"%s\".\n"),
4732 _unicode_linestyle2string(popt
->topt
.unicode_border_linestyle
));
4735 else if (strcmp(param
, "unicode_column_linestyle") == 0)
4737 printf(_("Unicode column line style is \"%s\".\n"),
4738 _unicode_linestyle2string(popt
->topt
.unicode_column_linestyle
));
4741 else if (strcmp(param
, "unicode_header_linestyle") == 0)
4743 printf(_("Unicode header line style is \"%s\".\n"),
4744 _unicode_linestyle2string(popt
->topt
.unicode_header_linestyle
));
4749 pg_log_error("\\pset: unknown option: %s", param
);
4757 * savePsetInfo: make a malloc'd copy of the data in *popt.
4759 * Possibly this should be somewhere else, but it's a bit specific to psql.
4762 savePsetInfo(const printQueryOpt
*popt
)
4764 printQueryOpt
*save
;
4766 save
= (printQueryOpt
*) pg_malloc(sizeof(printQueryOpt
));
4768 /* Flat-copy all the scalar fields, then duplicate sub-structures. */
4769 memcpy(save
, popt
, sizeof(printQueryOpt
));
4771 /* topt.line_style points to const data that need not be duplicated */
4772 if (popt
->topt
.fieldSep
.separator
)
4773 save
->topt
.fieldSep
.separator
= pg_strdup(popt
->topt
.fieldSep
.separator
);
4774 if (popt
->topt
.recordSep
.separator
)
4775 save
->topt
.recordSep
.separator
= pg_strdup(popt
->topt
.recordSep
.separator
);
4776 if (popt
->topt
.tableAttr
)
4777 save
->topt
.tableAttr
= pg_strdup(popt
->topt
.tableAttr
);
4778 if (popt
->nullPrint
)
4779 save
->nullPrint
= pg_strdup(popt
->nullPrint
);
4781 save
->title
= pg_strdup(popt
->title
);
4784 * footers and translate_columns are never set in psql's print settings,
4785 * so we needn't write code to duplicate them.
4787 Assert(popt
->footers
== NULL
);
4788 Assert(popt
->translate_columns
== NULL
);
4794 * restorePsetInfo: restore *popt from the previously-saved copy *save,
4798 restorePsetInfo(printQueryOpt
*popt
, printQueryOpt
*save
)
4800 /* Free all the old data we're about to overwrite the pointers to. */
4802 /* topt.line_style points to const data that need not be duplicated */
4803 free(popt
->topt
.fieldSep
.separator
);
4804 free(popt
->topt
.recordSep
.separator
);
4805 free(popt
->topt
.tableAttr
);
4806 free(popt
->nullPrint
);
4810 * footers and translate_columns are never set in psql's print settings,
4811 * so we needn't write code to duplicate them.
4813 Assert(popt
->footers
== NULL
);
4814 Assert(popt
->translate_columns
== NULL
);
4816 /* Now we may flat-copy all the fields, including pointers. */
4817 memcpy(popt
, save
, sizeof(printQueryOpt
));
4819 /* Lastly, free "save" ... but its sub-structures now belong to popt. */
4824 pset_bool_string(bool val
)
4826 return val
? "on" : "off";
4831 pset_quoted_string(const char *str
)
4833 char *ret
= pg_malloc(strlen(str
) * 2 + 3);
4845 else if (*str
== '\'')
4862 * Return a malloc'ed string for the \pset value.
4864 * Note that for some string parameters, print.c distinguishes between unset
4865 * and empty string, but for others it doesn't. This function should produce
4866 * output that produces the correct setting when fed back into \pset.
4869 pset_value_string(const char *param
, printQueryOpt
*popt
)
4871 Assert(param
!= NULL
);
4873 if (strcmp(param
, "border") == 0)
4874 return psprintf("%d", popt
->topt
.border
);
4875 else if (strcmp(param
, "columns") == 0)
4876 return psprintf("%d", popt
->topt
.columns
);
4877 else if (strcmp(param
, "csv_fieldsep") == 0)
4878 return pset_quoted_string(popt
->topt
.csvFieldSep
);
4879 else if (strcmp(param
, "expanded") == 0)
4880 return pstrdup(popt
->topt
.expanded
== 2
4882 : pset_bool_string(popt
->topt
.expanded
));
4883 else if (strcmp(param
, "fieldsep") == 0)
4884 return pset_quoted_string(popt
->topt
.fieldSep
.separator
4885 ? popt
->topt
.fieldSep
.separator
4887 else if (strcmp(param
, "fieldsep_zero") == 0)
4888 return pstrdup(pset_bool_string(popt
->topt
.fieldSep
.separator_zero
));
4889 else if (strcmp(param
, "footer") == 0)
4890 return pstrdup(pset_bool_string(popt
->topt
.default_footer
));
4891 else if (strcmp(param
, "format") == 0)
4892 return psprintf("%s", _align2string(popt
->topt
.format
));
4893 else if (strcmp(param
, "linestyle") == 0)
4894 return psprintf("%s", get_line_style(&popt
->topt
)->name
);
4895 else if (strcmp(param
, "null") == 0)
4896 return pset_quoted_string(popt
->nullPrint
4899 else if (strcmp(param
, "numericlocale") == 0)
4900 return pstrdup(pset_bool_string(popt
->topt
.numericLocale
));
4901 else if (strcmp(param
, "pager") == 0)
4902 return psprintf("%d", popt
->topt
.pager
);
4903 else if (strcmp(param
, "pager_min_lines") == 0)
4904 return psprintf("%d", popt
->topt
.pager_min_lines
);
4905 else if (strcmp(param
, "recordsep") == 0)
4906 return pset_quoted_string(popt
->topt
.recordSep
.separator
4907 ? popt
->topt
.recordSep
.separator
4909 else if (strcmp(param
, "recordsep_zero") == 0)
4910 return pstrdup(pset_bool_string(popt
->topt
.recordSep
.separator_zero
));
4911 else if (strcmp(param
, "tableattr") == 0)
4912 return popt
->topt
.tableAttr
? pset_quoted_string(popt
->topt
.tableAttr
) : pstrdup("");
4913 else if (strcmp(param
, "title") == 0)
4914 return popt
->title
? pset_quoted_string(popt
->title
) : pstrdup("");
4915 else if (strcmp(param
, "tuples_only") == 0)
4916 return pstrdup(pset_bool_string(popt
->topt
.tuples_only
));
4917 else if (strcmp(param
, "unicode_border_linestyle") == 0)
4918 return pstrdup(_unicode_linestyle2string(popt
->topt
.unicode_border_linestyle
));
4919 else if (strcmp(param
, "unicode_column_linestyle") == 0)
4920 return pstrdup(_unicode_linestyle2string(popt
->topt
.unicode_column_linestyle
));
4921 else if (strcmp(param
, "unicode_header_linestyle") == 0)
4922 return pstrdup(_unicode_linestyle2string(popt
->topt
.unicode_header_linestyle
));
4923 else if (strcmp(param
, "xheader_width") == 0)
4925 if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_FULL
)
4926 return(pstrdup("full"));
4927 else if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_COLUMN
)
4928 return(pstrdup("column"));
4929 else if (popt
->topt
.expanded_header_width_type
== PRINT_XHEADER_PAGE
)
4930 return(pstrdup("page"));
4933 /* must be PRINT_XHEADER_EXACT_WIDTH */
4935 snprintf(wbuff
, sizeof(wbuff
), "%d",
4936 popt
->topt
.expanded_header_exact_width
);
4937 return pstrdup(wbuff
);
4941 return pstrdup("ERROR");
4947 #define DEFAULT_SHELL "/bin/sh"
4950 * CMD.EXE is in different places in different Win32 releases so we
4951 * have to rely on the path to find it.
4953 #define DEFAULT_SHELL "cmd.exe"
4957 do_shell(const char *command
)
4965 const char *shellName
;
4967 shellName
= getenv("SHELL");
4969 if (shellName
== NULL
)
4970 shellName
= getenv("COMSPEC");
4972 if (shellName
== NULL
)
4973 shellName
= DEFAULT_SHELL
;
4975 /* See EDITOR handling comment for an explanation */
4977 sys
= psprintf("exec %s", shellName
);
4979 sys
= psprintf("\"%s\"", shellName
);
4981 result
= system(sys
);
4985 result
= system(command
);
4987 if (result
== 127 || result
== -1)
4989 pg_log_error("\\!: failed");
4996 * do_watch -- handler for \watch
4998 * We break this out of exec_command to avoid having to plaster "volatile"
4999 * onto a bunch of exec_command's variables to silence stupider compilers.
5002 do_watch(PQExpBuffer query_buf
, double sleep
)
5004 long sleep_ms
= (long) (sleep
* 1000);
5005 printQueryOpt myopt
= pset
.popt
;
5006 const char *strftime_fmt
;
5007 const char *user_title
;
5009 const char *pagerprog
= NULL
;
5010 FILE *pagerpipe
= NULL
;
5014 sigset_t sigalrm_sigchld_sigint
;
5015 sigset_t sigalrm_sigchld
;
5017 struct itimerval interval
;
5021 if (!query_buf
|| query_buf
->len
<= 0)
5023 pg_log_error("\\watch cannot be used with an empty query");
5028 sigemptyset(&sigalrm_sigchld_sigint
);
5029 sigaddset(&sigalrm_sigchld_sigint
, SIGCHLD
);
5030 sigaddset(&sigalrm_sigchld_sigint
, SIGALRM
);
5031 sigaddset(&sigalrm_sigchld_sigint
, SIGINT
);
5033 sigemptyset(&sigalrm_sigchld
);
5034 sigaddset(&sigalrm_sigchld
, SIGCHLD
);
5035 sigaddset(&sigalrm_sigchld
, SIGALRM
);
5037 sigemptyset(&sigint
);
5038 sigaddset(&sigint
, SIGINT
);
5041 * Block SIGALRM and SIGCHLD before we start the timer and the pager (if
5042 * configured), to avoid races. sigwait() will receive them.
5044 sigprocmask(SIG_BLOCK
, &sigalrm_sigchld
, NULL
);
5047 * Set a timer to interrupt sigwait() so we can run the query at the
5048 * requested intervals.
5050 interval
.it_value
.tv_sec
= sleep_ms
/ 1000;
5051 interval
.it_value
.tv_usec
= (sleep_ms
% 1000) * 1000;
5052 interval
.it_interval
= interval
.it_value
;
5053 if (setitimer(ITIMER_REAL
, &interval
, NULL
) < 0)
5055 pg_log_error("could not set timer: %m");
5061 * For \watch, we ignore the size of the result and always use the pager
5062 * if PSQL_WATCH_PAGER is set. We also ignore the regular PSQL_PAGER or
5063 * PAGER environment variables, because traditional pagers probably won't
5064 * be very useful for showing a stream of results.
5067 pagerprog
= getenv("PSQL_WATCH_PAGER");
5069 if (pagerprog
&& myopt
.topt
.pager
)
5072 disable_sigpipe_trap();
5073 pagerpipe
= popen(pagerprog
, "w");
5076 /* silently proceed without pager */
5077 restore_sigpipe_trap();
5081 * Choose format for timestamps. We might eventually make this a \pset
5082 * option. In the meantime, using a variable for the format suppresses
5083 * overly-anal-retentive gcc warnings about %c being Y2K sensitive.
5085 strftime_fmt
= "%c";
5088 * Set up rendering options, in particular, disable the pager unless
5089 * PSQL_WATCH_PAGER was successfully launched.
5092 myopt
.topt
.pager
= 0;
5096 * If there's a title in the user configuration, make sure we have room
5097 * for it in the title buffer. Allow 128 bytes for the timestamp plus 128
5098 * bytes for the rest.
5100 user_title
= myopt
.title
;
5101 title_len
= (user_title
? strlen(user_title
) : 0) + 256;
5102 title
= pg_malloc(title_len
);
5110 * Prepare title for output. Note that we intentionally include a
5111 * newline at the end of the title; this is somewhat historical but it
5112 * makes for reasonably nicely formatted output in simple cases.
5115 strftime(timebuf
, sizeof(timebuf
), strftime_fmt
, localtime(&timer
));
5118 snprintf(title
, title_len
, _("%s\t%s (every %gs)\n"),
5119 user_title
, timebuf
, sleep
);
5121 snprintf(title
, title_len
, _("%s (every %gs)\n"),
5123 myopt
.title
= title
;
5125 /* Run the query and print out the result */
5126 res
= PSQLexecWatch(query_buf
->data
, &myopt
, pagerpipe
);
5129 * PSQLexecWatch handles the case where we can no longer repeat the
5130 * query, and returns 0 or -1.
5135 if (pagerpipe
&& ferror(pagerpipe
))
5141 * Set up cancellation of 'watch' via SIGINT. We redo this each time
5142 * through the loop since it's conceivable something inside
5143 * PSQLexecWatch could change sigint_interrupt_jmp.
5145 if (sigsetjmp(sigint_interrupt_jmp
, 1) != 0)
5149 * Enable 'watch' cancellations and wait a while before running the
5150 * query again. Break the sleep into short intervals (at most 1s).
5152 sigint_interrupt_enabled
= true;
5153 for (long i
= sleep_ms
; i
> 0;)
5155 long s
= Min(i
, 1000L);
5157 pg_usleep(s
* 1000L);
5162 sigint_interrupt_enabled
= false;
5164 /* sigwait() will handle SIGINT. */
5165 sigprocmask(SIG_BLOCK
, &sigint
, NULL
);
5169 /* Wait for SIGINT, SIGCHLD or SIGALRM. */
5172 int signal_received
;
5174 errno
= sigwait(&sigalrm_sigchld_sigint
, &signal_received
);
5177 /* Some other signal arrived? */
5182 pg_log_error("could not wait for signals: %m");
5187 /* On ^C or pager exit, it's time to stop running the query. */
5188 if (signal_received
== SIGINT
|| signal_received
== SIGCHLD
)
5190 /* Otherwise, we must have SIGALRM. Time to run the query again. */
5194 /* Unblock SIGINT so that slow queries can be interrupted. */
5195 sigprocmask(SIG_UNBLOCK
, &sigint
, NULL
);
5204 restore_sigpipe_trap();
5209 * If the terminal driver echoed "^C", libedit/libreadline might be
5210 * confused about the cursor position. Therefore, inject a newline
5211 * before the next prompt is displayed. We only do this when not
5212 * using a pager, because pagers are expected to restore the screen to
5213 * a sane state on exit.
5215 fprintf(stdout
, "\n");
5220 /* Disable the interval timer. */
5221 memset(&interval
, 0, sizeof(interval
));
5222 setitimer(ITIMER_REAL
, &interval
, NULL
);
5223 /* Unblock SIGINT, SIGCHLD and SIGALRM. */
5224 sigprocmask(SIG_UNBLOCK
, &sigalrm_sigchld_sigint
, NULL
);
5232 * a little code borrowed from PSQLexec() to manage ECHO_HIDDEN output.
5233 * returns true unless we have ECHO_HIDDEN_NOEXEC.
5236 echo_hidden_command(const char *query
)
5238 if (pset
.echo_hidden
!= PSQL_ECHO_HIDDEN_OFF
)
5240 printf(_("********* QUERY **********\n"
5242 "**************************\n\n"), query
);
5246 fprintf(pset
.logfile
,
5247 _("********* QUERY **********\n"
5249 "**************************\n\n"), query
);
5250 fflush(pset
.logfile
);
5253 if (pset
.echo_hidden
== PSQL_ECHO_HIDDEN_NOEXEC
)
5260 * Look up the object identified by obj_type and desc. If successful,
5261 * store its OID in *obj_oid and return true, else return false.
5263 * Note that we'll fail if the object doesn't exist OR if there are multiple
5264 * matching candidates OR if there's something syntactically wrong with the
5265 * object description; unfortunately it can be hard to tell the difference.
5268 lookup_object_oid(EditableObjectType obj_type
, const char *desc
,
5272 PQExpBuffer query
= createPQExpBuffer();
5277 case EditableFunction
:
5280 * We have a function description, e.g. "x" or "x(int)". Issue a
5281 * query to retrieve the function's OID using a cast to regproc or
5282 * regprocedure (as appropriate).
5284 appendPQExpBufferStr(query
, "SELECT ");
5285 appendStringLiteralConn(query
, desc
, pset
.db
);
5286 appendPQExpBuffer(query
, "::pg_catalog.%s::pg_catalog.oid",
5287 strchr(desc
, '(') ? "regprocedure" : "regproc");
5293 * Convert view name (possibly schema-qualified) to OID. Note:
5294 * this code doesn't check if the relation is actually a view.
5295 * We'll detect that in get_create_object_cmd().
5297 appendPQExpBufferStr(query
, "SELECT ");
5298 appendStringLiteralConn(query
, desc
, pset
.db
);
5299 appendPQExpBufferStr(query
, "::pg_catalog.regclass::pg_catalog.oid");
5303 if (!echo_hidden_command(query
->data
))
5305 destroyPQExpBuffer(query
);
5308 res
= PQexec(pset
.db
, query
->data
);
5309 if (PQresultStatus(res
) == PGRES_TUPLES_OK
&& PQntuples(res
) == 1)
5310 *obj_oid
= atooid(PQgetvalue(res
, 0, 0));
5313 minimal_error_message(res
);
5318 destroyPQExpBuffer(query
);
5324 * Construct a "CREATE OR REPLACE ..." command that describes the specified
5325 * database object. If successful, the result is stored in buf.
5328 get_create_object_cmd(EditableObjectType obj_type
, Oid oid
,
5332 PQExpBuffer query
= createPQExpBuffer();
5337 case EditableFunction
:
5338 printfPQExpBuffer(query
,
5339 "SELECT pg_catalog.pg_get_functiondef(%u)",
5346 * pg_get_viewdef() just prints the query, so we must prepend
5347 * CREATE for ourselves. We must fully qualify the view name to
5348 * ensure the right view gets replaced. Also, check relation kind
5349 * to be sure it's a view.
5351 * Starting with PG 9.4, views may have WITH [LOCAL|CASCADED]
5352 * CHECK OPTION. These are not part of the view definition
5353 * returned by pg_get_viewdef() and so need to be retrieved
5354 * separately. Materialized views (introduced in 9.3) may have
5355 * arbitrary storage parameter reloptions.
5357 if (pset
.sversion
>= 90400)
5359 printfPQExpBuffer(query
,
5360 "SELECT nspname, relname, relkind, "
5361 "pg_catalog.pg_get_viewdef(c.oid, true), "
5362 "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
5363 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
5364 "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
5365 "FROM pg_catalog.pg_class c "
5366 "LEFT JOIN pg_catalog.pg_namespace n "
5367 "ON c.relnamespace = n.oid WHERE c.oid = %u",
5372 printfPQExpBuffer(query
,
5373 "SELECT nspname, relname, relkind, "
5374 "pg_catalog.pg_get_viewdef(c.oid, true), "
5375 "c.reloptions AS reloptions, "
5376 "NULL AS checkoption "
5377 "FROM pg_catalog.pg_class c "
5378 "LEFT JOIN pg_catalog.pg_namespace n "
5379 "ON c.relnamespace = n.oid WHERE c.oid = %u",
5385 if (!echo_hidden_command(query
->data
))
5387 destroyPQExpBuffer(query
);
5390 res
= PQexec(pset
.db
, query
->data
);
5391 if (PQresultStatus(res
) == PGRES_TUPLES_OK
&& PQntuples(res
) == 1)
5393 resetPQExpBuffer(buf
);
5396 case EditableFunction
:
5397 appendPQExpBufferStr(buf
, PQgetvalue(res
, 0, 0));
5402 char *nspname
= PQgetvalue(res
, 0, 0);
5403 char *relname
= PQgetvalue(res
, 0, 1);
5404 char *relkind
= PQgetvalue(res
, 0, 2);
5405 char *viewdef
= PQgetvalue(res
, 0, 3);
5406 char *reloptions
= PQgetvalue(res
, 0, 4);
5407 char *checkoption
= PQgetvalue(res
, 0, 5);
5410 * If the backend ever supports CREATE OR REPLACE
5411 * MATERIALIZED VIEW, allow that here; but as of today it
5412 * does not, so editing a matview definition in this way
5418 case RELKIND_MATVIEW
:
5419 appendPQExpBufferStr(buf
, "CREATE OR REPLACE MATERIALIZED VIEW ");
5423 appendPQExpBufferStr(buf
, "CREATE OR REPLACE VIEW ");
5426 pg_log_error("\"%s.%s\" is not a view",
5431 appendPQExpBuffer(buf
, "%s.", fmtId(nspname
));
5432 appendPQExpBufferStr(buf
, fmtId(relname
));
5434 /* reloptions, if not an empty array "{}" */
5435 if (reloptions
!= NULL
&& strlen(reloptions
) > 2)
5437 appendPQExpBufferStr(buf
, "\n WITH (");
5438 if (!appendReloptionsArray(buf
, reloptions
, "",
5440 standard_strings()))
5442 pg_log_error("could not parse reloptions array");
5445 appendPQExpBufferChar(buf
, ')');
5448 /* View definition from pg_get_viewdef (a SELECT query) */
5449 appendPQExpBuffer(buf
, " AS\n%s", viewdef
);
5451 /* Get rid of the semicolon that pg_get_viewdef appends */
5452 if (buf
->len
> 0 && buf
->data
[buf
->len
- 1] == ';')
5453 buf
->data
[--(buf
->len
)] = '\0';
5455 /* WITH [LOCAL|CASCADED] CHECK OPTION */
5456 if (checkoption
&& checkoption
[0] != '\0')
5457 appendPQExpBuffer(buf
, "\n WITH %s CHECK OPTION",
5462 /* Make sure result ends with a newline */
5463 if (buf
->len
> 0 && buf
->data
[buf
->len
- 1] != '\n')
5464 appendPQExpBufferChar(buf
, '\n');
5468 minimal_error_message(res
);
5473 destroyPQExpBuffer(query
);
5479 * If the given argument of \ef or \ev ends with a line number, delete the line
5480 * number from the argument string and return it as an integer. (We need
5481 * this kluge because we're too lazy to parse \ef's function or \ev's view
5482 * argument carefully --- we just slop it up in OT_WHOLE_LINE mode.)
5484 * Returns -1 if no line number is present, 0 on error, or a positive value
5488 strip_lineno_from_objdesc(char *obj
)
5493 if (!obj
|| obj
[0] == '\0')
5496 c
= obj
+ strlen(obj
) - 1;
5499 * This business of parsing backwards is dangerous as can be in a
5500 * multibyte environment: there is no reason to believe that we are
5501 * looking at the first byte of a character, nor are we necessarily
5502 * working in a "safe" encoding. Fortunately the bitpatterns we are
5503 * looking for are unlikely to occur as non-first bytes, but beware of
5504 * trying to expand the set of cases that can be recognized. We must
5505 * guard the <ctype.h> macros by using isascii() first, too.
5508 /* skip trailing whitespace */
5509 while (c
> obj
&& isascii((unsigned char) *c
) && isspace((unsigned char) *c
))
5512 /* must have a digit as last non-space char */
5513 if (c
== obj
|| !isascii((unsigned char) *c
) || !isdigit((unsigned char) *c
))
5516 /* find start of digit string */
5517 while (c
> obj
&& isascii((unsigned char) *c
) && isdigit((unsigned char) *c
))
5520 /* digits must be separated from object name by space or closing paren */
5521 /* notice also that we are not allowing an empty object name ... */
5522 if (c
== obj
|| !isascii((unsigned char) *c
) ||
5523 !(isspace((unsigned char) *c
) || *c
== ')'))
5526 /* parse digit string */
5531 pg_log_error("invalid line number: %s", c
);
5535 /* strip digit string from object name */
5542 * Count number of lines in the buffer.
5543 * This is used to test if pager is needed or not.
5546 count_lines_in_buf(PQExpBuffer buf
)
5549 const char *lines
= buf
->data
;
5551 while (*lines
!= '\0')
5554 /* find start of next line */
5555 lines
= strchr(lines
, '\n');
5565 * Write text at *lines to output with line numbers.
5567 * If header_keyword isn't NULL, then line 1 should be the first line beginning
5568 * with header_keyword; lines before that are unnumbered.
5570 * Caution: this scribbles on *lines.
5573 print_with_linenumbers(FILE *output
, char *lines
,
5574 const char *header_keyword
)
5576 bool in_header
= (header_keyword
!= NULL
);
5577 size_t header_sz
= in_header
? strlen(header_keyword
) : 0;
5580 while (*lines
!= '\0')
5584 if (in_header
&& strncmp(lines
, header_keyword
, header_sz
) == 0)
5587 /* increment lineno only for body's lines */
5591 /* find and mark end of current line */
5592 eol
= strchr(lines
, '\n');
5596 /* show current line as appropriate */
5598 fprintf(output
, " %s\n", lines
);
5600 fprintf(output
, "%-7d %s\n", lineno
, lines
);
5602 /* advance to next line, if any */
5610 * Report just the primary error; this is to avoid cluttering the output
5611 * with, for instance, a redisplay of the internally generated query
5614 minimal_error_message(PGresult
*res
)
5619 msg
= createPQExpBuffer();
5621 fld
= PQresultErrorField(res
, PG_DIAG_SEVERITY
);
5623 printfPQExpBuffer(msg
, "%s: ", fld
);
5625 printfPQExpBuffer(msg
, "ERROR: ");
5626 fld
= PQresultErrorField(res
, PG_DIAG_MESSAGE_PRIMARY
);
5628 appendPQExpBufferStr(msg
, fld
);
5630 appendPQExpBufferStr(msg
, "(not available)");
5631 appendPQExpBufferChar(msg
, '\n');
5633 pg_log_error("%s", msg
->data
);
5635 destroyPQExpBuffer(msg
);