/*
* psql - the PostgreSQL interactive terminal
*
- * Copyright (c) 2000-2018, PostgreSQL Global Development Group
+ * Copyright (c) 2000-2019, PostgreSQL Global Development Group
*
* src/bin/psql/command.c
*/
#include "libpq-fe.h"
#include "pqexpbuffer.h"
+#include "common/logging.h"
+#include "fe_utils/print.h"
#include "fe_utils/string_utils.h"
#include "common.h"
#include "input.h"
#include "large_obj.h"
#include "mainloop.h"
-#include "fe_utils/print.h"
#include "psqlscanslash.h"
#include "settings.h"
#include "variables.h"
static void minimal_error_message(PGresult *res);
static void printSSLInfo(void);
+static void printGSSInfo(void);
static bool printPsetInfo(const char *param, struct printQueryOpt *popt);
static char *pset_value_string(const char *param, struct printQueryOpt *popt);
if (status == PSQL_CMD_UNKNOWN)
{
+ pg_log_error("invalid command \\%s", cmd);
if (pset.cur_cmd_interactive)
- psql_error("Invalid command \\%s. Try \\? for help.\n", cmd);
- else
- psql_error("invalid command \\%s\n", cmd);
+ pg_log_info("Try \\? for help.");
status = PSQL_CMD_ERROR;
}
OT_NORMAL, NULL, false)))
{
if (active_branch)
- psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg);
+ pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd, arg);
free(arg);
}
conditional_stack_pop(cstack);
if (pset.cur_cmd_interactive && !active_branch &&
!is_branching_command(cmd))
{
- psql_error("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n",
+ pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
cmd);
}
pw = getpwuid(user_id);
if (!pw)
{
- psql_error("could not get home directory for user ID %ld: %s\n",
+ pg_log_error("could not get home directory for user ID %ld: %s",
(long) user_id,
errno ? strerror(errno) : _("user does not exist"));
exit(EXIT_FAILURE);
if (chdir(dir) == -1)
{
- psql_error("\\%s: could not change directory to \"%s\": %s\n",
- cmd, dir, strerror(errno));
+ pg_log_error("\\%s: could not change directory to \"%s\": %m",
+ cmd, dir);
success = false;
}
else
{
char *host = PQhost(pset.db);
+ char *hostaddr = PQhostaddr(pset.db);
- /* If the host is an absolute path, the connection is via socket */
+ /*
+ * If the host is an absolute path, the connection is via socket
+ * unless overridden by hostaddr
+ */
if (is_absolute_path(host))
- printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
- db, PQuser(pset.db), host, PQport(pset.db));
+ {
+ if (hostaddr && *hostaddr)
+ printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
+ db, PQuser(pset.db), hostaddr, PQport(pset.db));
+ else
+ printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
+ db, PQuser(pset.db), host, PQport(pset.db));
+ }
else
- printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
- db, PQuser(pset.db), host, PQport(pset.db));
+ {
+ if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
+ printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
+ db, PQuser(pset.db), host, hostaddr, PQport(pset.db));
+ else
+ printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
+ db, PQuser(pset.db), host, PQport(pset.db));
+ }
printSSLInfo();
+ printGSSInfo();
}
}
case 'p':
success = permissionsList(pattern);
break;
+ case 'P':
+ {
+ switch (cmd[2])
+ {
+ case '\0':
+ case '+':
+ case 't':
+ case 'i':
+ case 'n':
+ success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ break;
+ default:
+ status = PSQL_CMD_UNKNOWN;
+ break;
+ }
+ }
+ break;
case 'T':
success = describeTypes(pattern, show_verbose, show_system);
break;
{
if (!query_buf)
{
- psql_error("no query buffer\n");
+ pg_log_error("no query buffer");
status = PSQL_CMD_ERROR;
}
else
lineno = atoi(ln);
if (lineno < 1)
{
- psql_error("invalid line number: %s\n", ln);
+ pg_log_error("invalid line number: %s", ln);
status = PSQL_CMD_ERROR;
}
}
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf));
if (is_func)
- psql_error("The server (version %s) does not support editing function source.\n",
+ pg_log_error("The server (version %s) does not support editing function source.",
sverbuf);
else
- psql_error("The server (version %s) does not support editing view definitions.\n",
+ pg_log_error("The server (version %s) does not support editing view definitions.",
sverbuf);
status = PSQL_CMD_ERROR;
}
else if (!query_buf)
{
- psql_error("no query buffer\n");
+ pg_log_error("no query buffer");
status = PSQL_CMD_ERROR;
}
else
{
/* set encoding */
if (PQsetClientEncoding(pset.db, encoding) == -1)
- psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
+ pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
else
{
/* save encoding info into psql internal data */
PQSHOW_CONTEXT_ALWAYS);
if (msg)
{
- psql_error("%s", msg);
+ pg_log_error("%s", msg);
PQfreemem(msg);
}
else
if (!fname)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else
break;
case IFSTATE_ELSE_TRUE:
case IFSTATE_ELSE_FALSE:
- psql_error("\\elif: cannot occur after \\else\n");
+ pg_log_error("\\elif: cannot occur after \\else");
success = false;
break;
case IFSTATE_NONE:
/* no \if to elif from */
- psql_error("\\elif: no matching \\if\n");
+ pg_log_error("\\elif: no matching \\if");
success = false;
break;
}
break;
case IFSTATE_ELSE_TRUE:
case IFSTATE_ELSE_FALSE:
- psql_error("\\else: cannot occur after \\else\n");
+ pg_log_error("\\else: cannot occur after \\else");
success = false;
break;
case IFSTATE_NONE:
/* no \if to else from */
- psql_error("\\else: no matching \\if\n");
+ pg_log_error("\\else: no matching \\if");
success = false;
break;
}
break;
case IFSTATE_NONE:
/* no \if to end */
- psql_error("\\endif: no matching \\if\n");
+ pg_log_error("\\endif: no matching \\if");
success = false;
break;
}
{
if (!opt2)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else
{
if (!opt1)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else
{
if (!opt1)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else
if (strcmp(pw1, pw2) != 0)
{
- psql_error("Passwords didn't match.\n");
+ pg_log_error("Passwords didn't match.");
success = false;
}
else
if (!encrypted_password)
{
- psql_error("%s", PQerrorMessage(pset.db));
+ pg_log_info("%s", PQerrorMessage(pset.db));
success = false;
}
else
if (!arg1)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else
result = gets_fromFile(stdin);
if (!result)
{
- psql_error("\\%s: could not read value for variable\n",
+ pg_log_error("\\%s: could not read value for variable",
cmd);
success = false;
}
int i;
static const char *const my_list[] = {
- "border", "columns", "expanded", "fieldsep", "fieldsep_zero",
- "footer", "format", "linestyle", "null",
+ "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
+ "fieldsep_zero", "footer", "format", "linestyle", "null",
"numericlocale", "pager", "pager_min_lines",
"recordsep", "recordsep_zero",
"tableattr", "title", "tuples_only",
if (!envvar)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else if (strchr(envvar, '=') != NULL)
{
- psql_error("\\%s: environment variable name must not contain \"=\"\n",
+ pg_log_error("\\%s: environment variable name must not contain \"=\"",
cmd);
success = false;
}
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf));
if (is_func)
- psql_error("The server (version %s) does not support showing function source.\n",
+ pg_log_error("The server (version %s) does not support showing function source.",
sverbuf);
else
- psql_error("The server (version %s) does not support showing view definitions.\n",
+ pg_log_error("The server (version %s) does not support showing view definitions.",
sverbuf);
status = PSQL_CMD_ERROR;
}
else if (!obj_desc)
{
if (is_func)
- psql_error("function name is required\n");
+ pg_log_error("function name is required");
else
- psql_error("view name is required\n");
+ pg_log_error("view name is required");
status = PSQL_CMD_ERROR;
}
else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
if (!opt)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
success = false;
}
else if (!SetVariable(pset.vars, opt, NULL))
if (!query_buf)
{
- psql_error("no query buffer\n");
+ pg_log_error("no query buffer");
status = PSQL_CMD_ERROR;
}
else
{
if (!fname)
{
- psql_error("\\%s: missing required argument\n", cmd);
+ pg_log_error("\\%s: missing required argument", cmd);
status = PSQL_CMD_ERROR;
}
else
}
if (!fd)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
status = PSQL_CMD_ERROR;
}
}
if (result == EOF)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
status = PSQL_CMD_ERROR;
}
}
PGconn *o_conn = pset.db,
*n_conn;
char *password = NULL;
+ char *hostaddr = NULL;
bool keep_password;
bool has_connection_string;
bool reuse_previous;
* connect to the wrong database by using defaults, so require all
* parameters to be specified.
*/
- psql_error("All connection parameters must be supplied because no "
- "database connection exists\n");
+ pg_log_error("All connection parameters must be supplied because no "
+ "database connection exists");
return false;
}
}
/* grab missing values from the old connection */
- if (!user && reuse_previous)
- user = PQuser(o_conn);
- if (!host && reuse_previous)
- host = PQhost(o_conn);
- if (!port && reuse_previous)
- port = PQport(o_conn);
+ if (reuse_previous)
+ {
+ if (!user)
+ user = PQuser(o_conn);
+ if (host && strcmp(host, PQhost(o_conn)) == 0)
+ {
+ /*
+ * if we are targetting the same host, reuse its hostaddr for
+ * consistency
+ */
+ hostaddr = PQhostaddr(o_conn);
+ }
+ if (!host)
+ {
+ host = PQhost(o_conn);
+ /* also set hostaddr for consistency */
+ hostaddr = PQhostaddr(o_conn);
+ }
+ if (!port)
+ port = PQport(o_conn);
+ }
/*
* Any change in the parameters read above makes us discard the password.
while (true)
{
-#define PARAMS_ARRAY_SIZE 8
+#define PARAMS_ARRAY_SIZE 9
const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
int paramnum = -1;
keywords[++paramnum] = "host";
values[paramnum] = host;
+ if (hostaddr && *hostaddr)
+ {
+ keywords[++paramnum] = "hostaddr";
+ values[paramnum] = hostaddr;
+ }
keywords[++paramnum] = "port";
values[paramnum] = port;
keywords[++paramnum] = "user";
*/
if (pset.cur_cmd_interactive)
{
- psql_error("%s", PQerrorMessage(n_conn));
+ pg_log_info("%s", PQerrorMessage(n_conn));
/* pset.db is left unmodified */
if (o_conn)
- psql_error("Previous connection kept\n");
+ pg_log_info("Previous connection kept");
}
else
{
- psql_error("\\connect: %s", PQerrorMessage(n_conn));
+ pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
if (o_conn)
{
PQfinish(o_conn);
param_is_newly_set(PQport(o_conn), PQport(pset.db)))
{
char *host = PQhost(pset.db);
+ char *hostaddr = PQhostaddr(pset.db);
/* If the host is an absolute path, the connection is via socket */
if (is_absolute_path(host))
- printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
- PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
+ {
+ if (hostaddr && *hostaddr)
+ printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
+ PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
+ else
+ printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
+ PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
+ }
else
- printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
- PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
+ {
+ if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
+ printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
+ PQdb(pset.db), PQuser(pset.db), host, hostaddr, PQport(pset.db));
+ else
+ printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
+ PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
+ }
}
else
printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
checkWin32Codepage();
#endif
printSSLInfo();
+ printGSSInfo();
}
}
(compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
}
+/*
+ * printGSSInfo
+ *
+ * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use
+ */
+static void
+printGSSInfo(void)
+{
+ if (!PQgssEncInUse(pset.db))
+ return; /* no GSSAPI encryption in use */
+
+ printf(_("GSSAPI Encrypted connection\n"));
+}
+
/*
* checkWin32Codepage
#endif
if (!editor_lineno_arg)
{
- psql_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n");
+ pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
return false;
}
}
#endif
result = system(sys);
if (result == -1)
- psql_error("could not start editor \"%s\"\n", editorName);
+ pg_log_error("could not start editor \"%s\"", editorName);
else if (result == 127)
- psql_error("could not start /bin/sh\n");
+ pg_log_error("could not start /bin/sh");
free(sys);
return result == 0;
ret = GetTempPath(MAXPGPATH, tmpdir);
if (ret == 0 || ret > MAXPGPATH)
{
- psql_error("could not locate temporary directory: %s\n",
+ pg_log_error("could not locate temporary directory: %s",
!ret ? strerror(errno) : "");
return false;
}
if (fd == -1 || !stream)
{
- psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno));
+ pg_log_error("could not open temporary file \"%s\": %m", fname);
error = true;
}
else
if (fwrite(query_buf->data, 1, ql, stream) != ql)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
if (fclose(stream) != 0)
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
if (remove(fname) != 0)
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
else if (fclose(stream) != 0)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
if (remove(fname) != 0)
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
}
if (!error && stat(fname, &before) != 0)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
if (!error && stat(fname, &after) != 0)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
stream = fopen(fname, PG_BINARY_R);
if (!stream)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
else
if (ferror(stream))
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
else if (edited)
{
if (remove(fname) == -1)
{
- psql_error("%s: %s\n", fname, strerror(errno));
+ pg_log_error("%s: %m", fname);
error = true;
}
}
if (!fd)
{
- psql_error("%s: %s\n", filename, strerror(errno));
+ pg_log_error("%s: %m", filename);
return EXIT_FAILURE;
}
}
oldfilename = pset.inputfile;
pset.inputfile = filename;
+ pg_logging_config(pset.inputfile ? 0 : PG_LOG_FLAG_TERSE);
+
result = MainLoop(fd);
if (fd != stdin)
fclose(fd);
pset.inputfile = oldfilename;
+
+ pg_logging_config(pset.inputfile ? 0 : PG_LOG_FLAG_TERSE);
+
return result;
}
case PRINT_NOTHING:
return "nothing";
break;
- case PRINT_UNALIGNED:
- return "unaligned";
- break;
case PRINT_ALIGNED:
return "aligned";
break;
- case PRINT_WRAPPED:
- return "wrapped";
+ case PRINT_ASCIIDOC:
+ return "asciidoc";
+ break;
+ case PRINT_CSV:
+ return "csv";
break;
case PRINT_HTML:
return "html";
break;
- case PRINT_ASCIIDOC:
- return "asciidoc";
- break;
case PRINT_LATEX:
return "latex";
break;
case PRINT_TROFF_MS:
return "troff-ms";
break;
+ case PRINT_UNALIGNED:
+ return "unaligned";
+ break;
+ case PRINT_WRAPPED:
+ return "wrapped";
+ break;
}
return "unknown";
}
/* set format */
if (strcmp(param, "format") == 0)
{
+ static const struct fmt
+ {
+ const char *name;
+ enum printFormat number;
+ } formats[] =
+ {
+ /* remember to update error message below when adding more */
+ {"aligned", PRINT_ALIGNED},
+ {"asciidoc", PRINT_ASCIIDOC},
+ {"csv", PRINT_CSV},
+ {"html", PRINT_HTML},
+ {"latex", PRINT_LATEX},
+ {"troff-ms", PRINT_TROFF_MS},
+ {"unaligned", PRINT_UNALIGNED},
+ {"wrapped", PRINT_WRAPPED}
+ };
+
if (!value)
;
- else if (pg_strncasecmp("unaligned", value, vallen) == 0)
- popt->topt.format = PRINT_UNALIGNED;
- else if (pg_strncasecmp("aligned", value, vallen) == 0)
- popt->topt.format = PRINT_ALIGNED;
- else if (pg_strncasecmp("wrapped", value, vallen) == 0)
- popt->topt.format = PRINT_WRAPPED;
- else if (pg_strncasecmp("html", value, vallen) == 0)
- popt->topt.format = PRINT_HTML;
- else if (pg_strncasecmp("asciidoc", value, vallen) == 0)
- popt->topt.format = PRINT_ASCIIDOC;
- else if (pg_strncasecmp("latex", value, vallen) == 0)
- popt->topt.format = PRINT_LATEX;
- else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
- popt->topt.format = PRINT_LATEX_LONGTABLE;
- else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
- popt->topt.format = PRINT_TROFF_MS;
else
{
- psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n");
- return false;
+ int match_pos = -1;
+
+ for (int i = 0; i < lengthof(formats); i++)
+ {
+ if (pg_strncasecmp(formats[i].name, value, vallen) == 0)
+ {
+ if (match_pos < 0)
+ match_pos = i;
+ else
+ {
+ pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
+ value,
+ formats[match_pos].name, formats[i].name);
+ return false;
+ }
+ }
+ }
+ if (match_pos >= 0)
+ popt->topt.format = formats[match_pos].number;
+ else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
+ {
+ /*
+ * We must treat latex-longtable specially because latex is a
+ * prefix of it; if both were in the table above, we'd think
+ * "latex" is ambiguous.
+ */
+ popt->topt.format = PRINT_LATEX_LONGTABLE;
+ }
+ else
+ {
+ pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
+ return false;
+ }
}
}
popt->topt.line_style = &pg_utf8format;
else
{
- psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
+ pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
return false;
}
}
refresh_utf8format(&(popt->topt));
else
{
- psql_error("\\pset: allowed Unicode border line styles are single, double\n");
+ pg_log_error("\\pset: allowed Unicode border line styles are single, double");
return false;
}
}
refresh_utf8format(&(popt->topt));
else
{
- psql_error("\\pset: allowed Unicode column line styles are single, double\n");
+ pg_log_error("\\pset: allowed Unicode column line styles are single, double");
return false;
}
}
refresh_utf8format(&(popt->topt));
else
{
- psql_error("\\pset: allowed Unicode header line styles are single, double\n");
+ pg_log_error("\\pset: allowed Unicode header line styles are single, double");
return false;
}
}
popt->topt.expanded = !popt->topt.expanded;
}
+ /* field separator for CSV format */
+ else if (strcmp(param, "csv_fieldsep") == 0)
+ {
+ if (value)
+ {
+ /* CSV separator has to be a one-byte character */
+ if (strlen(value) != 1)
+ {
+ pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
+ return false;
+ }
+ if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
+ {
+ pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
+ return false;
+ }
+ popt->topt.csvFieldSep[0] = value[0];
+ }
+ }
+
/* locale-aware numeric output */
else if (strcmp(param, "numericlocale") == 0)
{
}
else
{
- psql_error("\\pset: unknown option: %s\n", param);
+ pg_log_error("\\pset: unknown option: %s", param);
return false;
}
printf(_("Expanded display is off.\n"));
}
+ /* show field separator for CSV format */
+ else if (strcmp(param, "csv_fieldsep") == 0)
+ {
+ printf(_("Field separator for CSV is \"%s\".\n"),
+ popt->topt.csvFieldSep);
+ }
+
/* show field separator for unaligned text */
else if (strcmp(param, "fieldsep") == 0)
{
else
{
- psql_error("\\pset: unknown option: %s\n", param);
+ pg_log_error("\\pset: unknown option: %s", param);
return false;
}
return psprintf("%d", popt->topt.border);
else if (strcmp(param, "columns") == 0)
return psprintf("%d", popt->topt.columns);
+ else if (strcmp(param, "csv_fieldsep") == 0)
+ return pset_quoted_string(popt->topt.csvFieldSep);
else if (strcmp(param, "expanded") == 0)
return pstrdup(popt->topt.expanded == 2
? "auto"
if (result == 127 || result == -1)
{
- psql_error("\\!: failed\n");
+ pg_log_error("\\!: failed");
return false;
}
return true;
if (!query_buf || query_buf->len <= 0)
{
- psql_error(_("\\watch cannot be used with an empty query\n"));
+ pg_log_error("\\watch cannot be used with an empty query");
return false;
}
printfPQExpBuffer(query,
"SELECT nspname, relname, relkind, "
"pg_catalog.pg_get_viewdef(c.oid, true), "
- "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
+ "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
"FROM pg_catalog.pg_class c "
appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
break;
default:
- psql_error("\"%s.%s\" is not a view\n",
+ pg_log_error("\"%s.%s\" is not a view",
nspname, relname);
result = false;
break;
pset.encoding,
standard_strings()))
{
- psql_error("could not parse reloptions array\n");
+ pg_log_error("could not parse reloptions array");
result = false;
}
appendPQExpBufferChar(buf, ')');
lineno = atoi(c);
if (lineno < 1)
{
- psql_error("invalid line number: %s\n", c);
+ pg_log_error("invalid line number: %s", c);
return 0;
}
appendPQExpBufferStr(msg, "(not available)");
appendPQExpBufferChar(msg, '\n');
- psql_error("%s", msg->data);
+ pg_log_error("%s", msg->data);
destroyPQExpBuffer(msg);
}