*** a/doc/src/sgml/ref/psql-ref.sgml
--- b/doc/src/sgml/ref/psql-ref.sgml
***************
*** 2827,2833 **** bar
they are sent to the server. The switch for this is
. If set to errors then only
failed queries are displayed on standard error output. The switch
! for this is .
--- 2827,2835 ----
they are sent to the server. The switch for this is
. If set to errors then only
failed queries are displayed on standard error output. The switch
! for this is . If unset, or if set to
! none (or any other value than those above) then
! no queries are displayed.
***************
*** 2892,2899 **** bar
list. If set to a value of ignoredups, lines
matching the previous history line are not entered. A value of
ignoreboth combines the two options. If
! unset, or if set to any other value than those above, all lines
! read in interactive mode are saved on the history list.
--- 2894,2902 ----
list. If set to a value of ignoredups, lines
matching the previous history line are not entered. A value of
ignoreboth combines the two options. If
! unset, or if set to none (or any other value
! than those above), all lines read in interactive mode are
! saved on the history list.
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
***************
*** 813,820 **** static char *_complete_from_query(int is_schema_query,
const char *text, int state);
static char *complete_from_list(const char *text, int state);
static char *complete_from_const(const char *text, int state);
static char **complete_from_variables(const char *text,
! const char *prefix, const char *suffix);
static char *complete_from_files(const char *text, int state);
static char *pg_strdup_keyword_case(const char *s, const char *ref);
--- 813,823 ----
const char *text, int state);
static char *complete_from_list(const char *text, int state);
static char *complete_from_const(const char *text, int state);
+ static void append_variable_names(char ***varnames, int *nvars,
+ int *maxvars, const char *varname,
+ const char *prefix, const char *suffix);
static char **complete_from_variables(const char *text,
! const char *prefix, const char *suffix, bool need_value);
static char *complete_from_files(const char *text, int state);
static char *pg_strdup_keyword_case(const char *s, const char *ref);
***************
*** 925,935 **** psql_completion(const char *text, int start, int end)
else if (text[0] == ':' && text[1] != ':')
{
if (text[1] == '\'')
! matches = complete_from_variables(text, ":'", "'");
else if (text[1] == '"')
! matches = complete_from_variables(text, ":\"", "\"");
else
! matches = complete_from_variables(text, ":", "");
}
/* If no previous word, suggest one of the basic sql commands */
--- 928,938 ----
else if (text[0] == ':' && text[1] != ':')
{
if (text[1] == '\'')
! matches = complete_from_variables(text, ":'", "'", true);
else if (text[1] == '"')
! matches = complete_from_variables(text, ":\"", "\"", true);
else
! matches = complete_from_variables(text, ":", "", true);
}
/* If no previous word, suggest one of the basic sql commands */
***************
*** 3604,3612 **** psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST_CS(my_list);
}
}
else if (strcmp(prev_wd, "\\set") == 0)
{
! matches = complete_from_variables(text, "", "");
}
else if (strcmp(prev_wd, "\\sf") == 0 || strcmp(prev_wd, "\\sf+") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
--- 3607,3677 ----
COMPLETE_WITH_LIST_CS(my_list);
}
}
+ else if (strcmp(prev_wd, "\\unset") == 0)
+ {
+ matches = complete_from_variables(text, "", "", true);
+ }
else if (strcmp(prev_wd, "\\set") == 0)
{
! matches = complete_from_variables(text, "", "", false);
! }
! else if (strcmp(prev2_wd, "\\set") == 0)
! {
! static const char *const boolean_value_list[] =
! {"on", "off", NULL};
!
! if (strcmp(prev_wd, "AUTOCOMMIT") == 0)
! COMPLETE_WITH_LIST_CS(boolean_value_list);
! else if (strcmp(prev_wd, "COMP_KEYWORD_CASE") == 0)
! {
! static const char *const my_list[] =
! {"lower", "upper", "preserve-lower", "preserve-upper", NULL};
!
! COMPLETE_WITH_LIST_CS(my_list);
! }
! else if (strcmp(prev_wd, "ECHO") == 0)
! {
! static const char *const my_list[] =
! {"errors", "queries", "all", "none", NULL};
!
! COMPLETE_WITH_LIST_CS(my_list);
! }
! else if (strcmp(prev_wd, "ECHO_HIDDEN") == 0)
! {
! static const char *const my_list[] =
! {"noexec", "off", "on", NULL};
!
! COMPLETE_WITH_LIST_CS(my_list);
! }
! else if (strcmp(prev_wd, "HISTCONTROL") == 0)
! {
! static const char *const my_list[] =
! {"ignorespace", "ignoredups", "ignoreboth", "none", NULL};
!
! COMPLETE_WITH_LIST_CS(my_list);
! }
! else if (strcmp(prev_wd, "ON_ERROR_ROLLBACK") == 0)
! {
! static const char *const my_list[] =
! {"on", "off", "interactive", NULL};
!
! COMPLETE_WITH_LIST_CS(my_list);
! }
! else if (strcmp(prev_wd, "ON_ERROR_STOP") == 0)
! COMPLETE_WITH_LIST_CS(boolean_value_list);
! else if (strcmp(prev_wd, "QUIET") == 0)
! COMPLETE_WITH_LIST_CS(boolean_value_list);
! else if (strcmp(prev_wd, "SINGLELINE") == 0)
! COMPLETE_WITH_LIST_CS(boolean_value_list);
! else if (strcmp(prev_wd, "SINGLESTEP") == 0)
! COMPLETE_WITH_LIST_CS(boolean_value_list);
! else if (strcmp(prev_wd, "VERBOSITY") == 0)
! {
! static const char *const my_list[] =
! {"default", "verbose", "terse", NULL};
!
! COMPLETE_WITH_LIST_CS(my_list);
! }
}
else if (strcmp(prev_wd, "\\sf") == 0 || strcmp(prev_wd, "\\sf+") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
***************
*** 4053,4064 **** complete_from_const(const char *text, int state)
/*
* This function supports completion with the name of a psql variable.
* The variable names can be prefixed and suffixed with additional text
! * to support quoting usages.
*/
static char **
! complete_from_variables(const char *text, const char *prefix, const char *suffix)
{
char **matches;
char **varnames;
--- 4118,4156 ----
/*
+ * This function appends the variable name with prefix and suffix to
+ * the variable names array.
+ */
+ static void
+ append_variable_names(char ***varnames, int *nvars,
+ int *maxvars, const char *varname,
+ const char *prefix, const char *suffix)
+ {
+ if (*nvars >= *maxvars)
+ {
+ *maxvars *= 2;
+ *varnames = (char **) realloc(*varnames,
+ ((*maxvars) + 1) * sizeof(char *));
+ if (!(*varnames))
+ {
+ psql_error("out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ (*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
+ }
+
+
+ /*
* This function supports completion with the name of a psql variable.
* The variable names can be prefixed and suffixed with additional text
! * to support quoting usages. If need_value is true, only the variables
! * that have the set values are picked up.
*/
static char **
! complete_from_variables(const char *text, const char *prefix, const char *suffix,
! bool need_value)
{
char **matches;
char **varnames;
***************
*** 4067,4089 **** complete_from_variables(const char *text, const char *prefix, const char *suffix
int i;
struct _variable *ptr;
varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
for (ptr = pset.vars->next; ptr; ptr = ptr->next)
{
! if (nvars >= maxvars)
{
! maxvars *= 2;
! varnames = (char **) realloc(varnames,
! (maxvars + 1) * sizeof(char *));
! if (!varnames)
! {
! psql_error("out of memory\n");
! exit(EXIT_FAILURE);
! }
}
!
! varnames[nvars++] = psprintf("%s%s%s", prefix, ptr->name, suffix);
}
varnames[nvars] = NULL;
--- 4159,4192 ----
int i;
struct _variable *ptr;
+ static const char *const known_varnames[] = {
+ "AUTOCOMMIT", "COMP_KEYWORD_CASE", "DBNAME", "ECHO", "ECHO_HIDDEN",
+ "ENCODING", "FETCH_COUNT", "HISTCONTROL", "HISTFILE", "HISTSIZE",
+ "HOST", "IGNOREEOF", "LASTOID", "ON_ERROR_ROLLBACK", "ON_ERROR_STOP",
+ "PORT", "PROMPT1", "PROMPT2", "PROMPT3", "QUIET", "SINGLELINE",
+ "SINGLESTEP", "USER", "VERBOSITY", NULL
+ };
+
varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
+ if (!need_value)
+ {
+ for (i = 0; known_varnames[i] && nvars < maxvars; i++)
+ append_variable_names(&varnames, &nvars, &maxvars,
+ known_varnames[i], prefix, suffix);
+ }
+
for (ptr = pset.vars->next; ptr; ptr = ptr->next)
{
! if (need_value && !(ptr->value))
! continue;
! for (i = 0; known_varnames[i]; i++) /* remove duplicate entry */
{
! if (strcmp(ptr->name, known_varnames[i]) == 0)
! continue;
}
! append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
! prefix, suffix);
}
varnames[nvars] = NULL;