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