On Sat, Aug 9, 2014 at 4:16 AM, Pavel Stehule <pavel.steh...@gmail.com> wrote: > Hi > > > 2014-08-08 13:58 GMT+02:00 Fujii Masao <masao.fu...@gmail.com>: > >> On Fri, Aug 8, 2014 at 4:31 AM, Pavel Stehule <pavel.steh...@gmail.com> >> wrote: >> > >> > >> > >> > 2014-08-07 7:10 GMT+02:00 Fujii Masao <masao.fu...@gmail.com>: >> > >> >> On Thu, Aug 7, 2014 at 6:26 AM, Pavel Stehule <pavel.steh...@gmail.com> >> >> wrote: >> >> > Hello >> >> > >> >> > updated version patch in attachment >> >> >> >> Thanks! But ISTM you forgot to attached the patch. >> > >> > >> > grr .. I am sorry >> >> No problem. Thanks for the patch! Attached is the revised version of the >> patch. >> >> >> >> + /* all psql known variables are included in list by default */ >> >> >> + for (known_varname = known_varnames; *known_varname; >> >> >> known_varname++) >> >> >> + varnames[nvars++] = pg_strdup(*known_varname); >> >> >> >> >> >> Don't we need to append both prefix and suffix to even known >> >> >> variables? >> >> > >> >> > >> >> > ??? I am not sure if I understand well - probably system "read only" >> >> > variables as DBNAME, USER, VERSION should not be there >> >> >> >> I had that question because complete_from_variables() is also called by >> >> the >> >> tab-completion of "\echo :" and it shows half-baked variables list. So >> >> I thought probably we need to change complete_from_variables() more to >> >> fix the problem. >> > >> > >> > I understand now. >> > >> > I fixed it. >> > >> > I have a question.\echo probably should not to show empty known >> > variable. >> > >> > data for autocomplete for \echo should be same as result of "\set" >> >> Agreed. I think that only the variables having the set values should be >> displayed in "\echo :" case. So I modified complete_from_variables() >> so that the unset variables are not shown in that case but all the >> variables >> are shown in the tab-completion of "\set". >> >> >> >> + else if (strcmp(prev2_wd, "\\set") == 0) >> >> >> + { >> >> >> + if (strcmp(prev_wd, "AUTOCOMMIT") == 0) >> >> >> >> >> >> ISTM that some psql variables like IGNOREEOF are not there. Why not? >> >> > >> >> > >> >> > yes, there are not complete for DBNAME, ENCODING, FETCH_COUNT, >> >> > HISTCONTROL, >> >> > HISTFILE, HISTSIZE, HOST, IGNOREEOFF, PROMPT*,USER, VERSION >> >> > >> >> > There are more reasons: >> >> > >> >> > * paremeter is not a enum (string, number or both): FETCH_COUNT, >> >> > PROMPT, >> >> > HISTSIZE, .. >> >> > >> >> > * variable is pseudo read only - change has not any effect: DBNAME, >> >> > ENCODING, VERSION >> >> >> >> So HISTCONTROL should be there because it doesn't have such reasons at >> >> all? >> >> >> > >> > yes >> >> ISTM that you forgot to add HISTCONTROL to your patch. So I just added >> that. >> >> I added the tab-completion for "\unset" command. Like "\echo :", only >> the variables having the set values should be displayed in "\unset" case. > > > perfect > >> >> >> I changed complete_from_variables() so that it checks the memory size of >> the variable array even when appending the known variables. If the memory >> size is not enough, it's dynamically increased. Practically this check >> would >> not be required because the initial size of the array is enough larger >> than >> the number of the known variables. I added this as the safe-guard. >> >> Typo: IGNOREEOFF -> IGNOREEOF >> >> I removed the value "none" from the value list of "ECHO" because it's not >> documented and a user might get confused when he or she sees the >> undocumented >> value "none". Thought? > > > isn't better to fix doc? I don't know any reason why we should not to > support "none"
I'm OK with this. The attached patch adds the support of "none" value both in ECHO and HISTCONTROL variables (because HISTCONTROL had the same problem as ECHO had), and also adds the description of that value into the document. > I looked to code, you removed a check against duplicate varname in list. Is > it ok? Oh, just revived that code. Regards, -- Fujii Masao
*** 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 <option>-e</option>. If set to <literal>errors</literal> then only failed queries are displayed on standard error output. The switch ! for this is <option>-b</option>. </para> </listitem> </varlistentry> --- 2827,2835 ---- they are sent to the server. The switch for this is <option>-e</option>. If set to <literal>errors</literal> then only failed queries are displayed on standard error output. The switch ! for this is <option>-b</option>. If unset, or if set to ! <literal>none</literal> (or any other value than those above) then ! no queries are displayed. </para> </listitem> </varlistentry> *************** *** 2892,2899 **** bar list. If set to a value of <literal>ignoredups</literal>, lines matching the previous history line are not entered. A value of <literal>ignoreboth</literal> 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. </para> <note> <para> --- 2894,2902 ---- list. If set to a value of <literal>ignoredups</literal>, lines matching the previous history line are not entered. A value of <literal>ignoreboth</literal> combines the two options. If ! unset, or if set to <literal>none</literal> (or any other value ! than those above), all lines read in interactive mode are ! saved on the history list. </para> <note> <para> *** 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;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers