summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-12-31 12:17:08 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-12-31 12:17:08 -0500
commit1773e07025e72b36fa5a1deeab55cd80f5383bcf (patch)
tree014f2678872f0cdc1415873a38aa1608575af271 /src
parent4c136b0b6389ce24838cc78eda5d213c15ac93fe (diff)
Improve consistency of parsing of psql's magic variables.
For simple boolean variables such as ON_ERROR_STOP, psql has for a long time recognized variant spellings of "on" and "off" (such as "1"/"0"), and it also made a point of warning you if you'd misspelled the setting. But these conveniences did not exist for other keyword-valued variables. In particular, though ECHO_HIDDEN and ON_ERROR_ROLLBACK include "on" and "off" as possible values, none of the alternative spellings for those were recognized; and to make matters worse the code would just silently assume "on" was meant for any unrecognized spelling. Several people have reported getting bitten by this, so let's fix it. In detail, this patch: * Allows all spellings recognized by ParseVariableBool() for ECHO_HIDDEN and ON_ERROR_ROLLBACK. * Reports a warning for unrecognized values for COMP_KEYWORD_CASE, ECHO, ECHO_HIDDEN, HISTCONTROL, ON_ERROR_ROLLBACK, and VERBOSITY. * Recognizes all values for all these variables case-insensitively; previously there was a mishmash of case-sensitive and case-insensitive behaviors. Back-patch to all supported branches. There is a small risk of breaking existing scripts that were accidentally failing to malfunction; but the consensus is that the chance of detecting real problems and preventing future mistakes outweighs this.
Diffstat (limited to 'src')
-rw-r--r--src/bin/psql/command.c18
-rw-r--r--src/bin/psql/startup.c56
-rw-r--r--src/bin/psql/variables.c15
-rw-r--r--src/bin/psql/variables.h2
4 files changed, 59 insertions, 32 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 3c727ac9bf3..fdb2404f5ed 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1252,7 +1252,7 @@ exec_command(const char *cmd,
OT_NORMAL, NULL, false);
if (opt)
- pset.timing = ParseVariableBool(opt);
+ pset.timing = ParseVariableBool(opt, "\\timing");
else
pset.timing = !pset.timing;
if (!pset.quiet)
@@ -2159,10 +2159,12 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
}
/* set expanded/vertical mode */
- else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
+ else if (strcmp(param, "x") == 0 ||
+ strcmp(param, "expanded") == 0 ||
+ strcmp(param, "vertical") == 0)
{
if (value)
- popt->topt.expanded = ParseVariableBool(value);
+ popt->topt.expanded = ParseVariableBool(value, param);
else
popt->topt.expanded = !popt->topt.expanded;
if (!quiet)
@@ -2175,7 +2177,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
else if (strcmp(param, "numericlocale") == 0)
{
if (value)
- popt->topt.numericLocale = ParseVariableBool(value);
+ popt->topt.numericLocale = ParseVariableBool(value, param);
else
popt->topt.numericLocale = !popt->topt.numericLocale;
if (!quiet)
@@ -2232,7 +2234,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
{
if (value)
- popt->topt.tuples_only = ParseVariableBool(value);
+ popt->topt.tuples_only = ParseVariableBool(value, param);
else
popt->topt.tuples_only = !popt->topt.tuples_only;
if (!quiet)
@@ -2286,10 +2288,12 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
if (value && pg_strcasecmp(value, "always") == 0)
popt->topt.pager = 2;
else if (value)
- if (ParseVariableBool(value))
+ {
+ if (ParseVariableBool(value, param))
popt->topt.pager = 1;
else
popt->topt.pager = 0;
+ }
else if (popt->topt.pager == 1)
popt->topt.pager = 0;
else
@@ -2309,7 +2313,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
else if (strcmp(param, "footer") == 0)
{
if (value)
- popt->default_footer = ParseVariableBool(value);
+ popt->default_footer = ParseVariableBool(value, param);
else
popt->default_footer = !popt->default_footer;
if (!quiet)
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 7b8078c21e4..af82e9f5b37 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -637,31 +637,31 @@ showVersion(void)
static void
autocommit_hook(const char *newval)
{
- pset.autocommit = ParseVariableBool(newval);
+ pset.autocommit = ParseVariableBool(newval, "AUTOCOMMIT");
}
static void
on_error_stop_hook(const char *newval)
{
- pset.on_error_stop = ParseVariableBool(newval);
+ pset.on_error_stop = ParseVariableBool(newval, "ON_ERROR_STOP");
}
static void
quiet_hook(const char *newval)
{
- pset.quiet = ParseVariableBool(newval);
+ pset.quiet = ParseVariableBool(newval, "QUIET");
}
static void
singleline_hook(const char *newval)
{
- pset.singleline = ParseVariableBool(newval);
+ pset.singleline = ParseVariableBool(newval, "SINGLELINE");
}
static void
singlestep_hook(const char *newval)
{
- pset.singlestep = ParseVariableBool(newval);
+ pset.singlestep = ParseVariableBool(newval, "SINGLESTEP");
}
static void
@@ -675,12 +675,18 @@ echo_hook(const char *newval)
{
if (newval == NULL)
pset.echo = PSQL_ECHO_NONE;
- else if (strcmp(newval, "queries") == 0)
+ else if (pg_strcasecmp(newval, "queries") == 0)
pset.echo = PSQL_ECHO_QUERIES;
- else if (strcmp(newval, "all") == 0)
+ else if (pg_strcasecmp(newval, "all") == 0)
pset.echo = PSQL_ECHO_ALL;
+ else if (pg_strcasecmp(newval, "none") == 0)
+ pset.echo = PSQL_ECHO_NONE;
else
+ {
+ psql_error("unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n",
+ newval, "ECHO", "none");
pset.echo = PSQL_ECHO_NONE;
+ }
}
static void
@@ -688,12 +694,12 @@ echo_hidden_hook(const char *newval)
{
if (newval == NULL)
pset.echo_hidden = PSQL_ECHO_HIDDEN_OFF;
- else if (strcmp(newval, "noexec") == 0)
+ else if (pg_strcasecmp(newval, "noexec") == 0)
pset.echo_hidden = PSQL_ECHO_HIDDEN_NOEXEC;
- else if (pg_strcasecmp(newval, "off") == 0)
- pset.echo_hidden = PSQL_ECHO_HIDDEN_OFF;
- else
+ else if (ParseVariableBool(newval, "ECHO_HIDDEN"))
pset.echo_hidden = PSQL_ECHO_HIDDEN_ON;
+ else /* ParseVariableBool printed msg if needed */
+ pset.echo_hidden = PSQL_ECHO_HIDDEN_OFF;
}
static void
@@ -703,10 +709,10 @@ on_error_rollback_hook(const char *newval)
pset.on_error_rollback = PSQL_ERROR_ROLLBACK_OFF;
else if (pg_strcasecmp(newval, "interactive") == 0)
pset.on_error_rollback = PSQL_ERROR_ROLLBACK_INTERACTIVE;
- else if (pg_strcasecmp(newval, "off") == 0)
- pset.on_error_rollback = PSQL_ERROR_ROLLBACK_OFF;
- else
+ else if (ParseVariableBool(newval, "ON_ERROR_ROLLBACK"))
pset.on_error_rollback = PSQL_ERROR_ROLLBACK_ON;
+ else /* ParseVariableBool printed msg if needed */
+ pset.on_error_rollback = PSQL_ERROR_ROLLBACK_OFF;
}
static void
@@ -714,14 +720,20 @@ histcontrol_hook(const char *newval)
{
if (newval == NULL)
pset.histcontrol = hctl_none;
- else if (strcmp(newval, "ignorespace") == 0)
+ else if (pg_strcasecmp(newval, "ignorespace") == 0)
pset.histcontrol = hctl_ignorespace;
- else if (strcmp(newval, "ignoredups") == 0)
+ else if (pg_strcasecmp(newval, "ignoredups") == 0)
pset.histcontrol = hctl_ignoredups;
- else if (strcmp(newval, "ignoreboth") == 0)
+ else if (pg_strcasecmp(newval, "ignoreboth") == 0)
pset.histcontrol = hctl_ignoreboth;
+ else if (pg_strcasecmp(newval, "none") == 0)
+ pset.histcontrol = hctl_none;
else
+ {
+ psql_error("unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n",
+ newval, "HISTCONTROL", "none");
pset.histcontrol = hctl_none;
+ }
}
static void
@@ -747,14 +759,18 @@ verbosity_hook(const char *newval)
{
if (newval == NULL)
pset.verbosity = PQERRORS_DEFAULT;
- else if (strcmp(newval, "default") == 0)
+ else if (pg_strcasecmp(newval, "default") == 0)
pset.verbosity = PQERRORS_DEFAULT;
- else if (strcmp(newval, "terse") == 0)
+ else if (pg_strcasecmp(newval, "terse") == 0)
pset.verbosity = PQERRORS_TERSE;
- else if (strcmp(newval, "verbose") == 0)
+ else if (pg_strcasecmp(newval, "verbose") == 0)
pset.verbosity = PQERRORS_VERBOSE;
else
+ {
+ psql_error("unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n",
+ newval, "VERBOSITY", "default");
pset.verbosity = PQERRORS_DEFAULT;
+ }
if (pset.db)
PQsetErrorVerbosity(pset.db, pset.verbosity);
diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c
index 38252893377..fd9a085b92b 100644
--- a/src/bin/psql/variables.c
+++ b/src/bin/psql/variables.c
@@ -49,11 +49,16 @@ GetVariable(VariableSpace space, const char *name)
}
/*
- * Try to interpret value as boolean value. Valid values are: true,
- * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
+ * Try to interpret "value" as boolean value.
+ *
+ * Valid values are: true, false, yes, no, on, off, 1, 0; as well as unique
+ * prefixes thereof.
+ *
+ * "name" is the name of the variable we're assigning to, to use in error
+ * report if any. Pass name == NULL to suppress the error report.
*/
bool
-ParseVariableBool(const char *value)
+ParseVariableBool(const char *value, const char *name)
{
size_t len;
@@ -82,7 +87,9 @@ ParseVariableBool(const char *value)
else
{
/* NULL is treated as false, so a non-matching value is 'true' */
- psql_error("unrecognized boolean value; assuming \"on\".\n");
+ if (name)
+ psql_error("unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n",
+ value, name, "on");
return true;
}
/* suppress compiler warning */
diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h
index 4197069b4b7..ed5ec372ca2 100644
--- a/src/bin/psql/variables.h
+++ b/src/bin/psql/variables.h
@@ -39,7 +39,7 @@ typedef struct _variable *VariableSpace;
VariableSpace CreateVariableSpace(void);
const char *GetVariable(VariableSpace space, const char *name);
-bool ParseVariableBool(const char *val);
+bool ParseVariableBool(const char *value, const char *name);
int ParseVariableNum(const char *val,
int defaultval,
int faultval,