@@ -813,8 +813,11 @@ static char *_complete_from_query(int is_schema_query,
813813const char * text ,int state );
814814static char * complete_from_list (const char * text ,int state );
815815static char * complete_from_const (const char * text ,int state );
816+ static void append_variable_names (char * * * varnames ,int * nvars ,
817+ int * maxvars ,const char * varname ,
818+ const char * prefix ,const char * suffix );
816819static char * * complete_from_variables (const char * text ,
817- const char * prefix ,const char * suffix );
820+ const char * prefix ,const char * suffix , bool need_value );
818821static char * complete_from_files (const char * text ,int state );
819822
820823static char * pg_strdup_keyword_case (const char * s ,const char * ref );
@@ -925,11 +928,11 @@ psql_completion(const char *text, int start, int end)
925928else if (text [0 ]== ':' && text [1 ]!= ':' )
926929{
927930if (text [1 ]== '\'' )
928- matches = complete_from_variables (text ,":'" ,"'" );
931+ matches = complete_from_variables (text ,":'" ,"'" , true );
929932else if (text [1 ]== '"' )
930- matches = complete_from_variables (text ,":\"" ,"\"" );
933+ matches = complete_from_variables (text ,":\"" ,"\"" , true );
931934else
932- matches = complete_from_variables (text ,":" ,"" );
935+ matches = complete_from_variables (text ,":" ,"" , true );
933936}
934937
935938/* If no previous word, suggest one of the basic sql commands */
@@ -3604,9 +3607,71 @@ psql_completion(const char *text, int start, int end)
36043607COMPLETE_WITH_LIST_CS (my_list );
36053608}
36063609}
3610+ else if (strcmp (prev_wd ,"\\unset" )== 0 )
3611+ {
3612+ matches = complete_from_variables (text ,"" ,"" , true);
3613+ }
36073614else if (strcmp (prev_wd ,"\\set" )== 0 )
36083615{
3609- matches = complete_from_variables (text ,"" ,"" );
3616+ matches = complete_from_variables (text ,"" ,"" , false);
3617+ }
3618+ else if (strcmp (prev2_wd ,"\\set" )== 0 )
3619+ {
3620+ static const char * const boolean_value_list []=
3621+ {"on" ,"off" ,NULL };
3622+
3623+ if (strcmp (prev_wd ,"AUTOCOMMIT" )== 0 )
3624+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3625+ else if (strcmp (prev_wd ,"COMP_KEYWORD_CASE" )== 0 )
3626+ {
3627+ static const char * const my_list []=
3628+ {"lower" ,"upper" ,"preserve-lower" ,"preserve-upper" ,NULL };
3629+
3630+ COMPLETE_WITH_LIST_CS (my_list );
3631+ }
3632+ else if (strcmp (prev_wd ,"ECHO" )== 0 )
3633+ {
3634+ static const char * const my_list []=
3635+ {"errors" ,"queries" ,"all" ,"none" ,NULL };
3636+
3637+ COMPLETE_WITH_LIST_CS (my_list );
3638+ }
3639+ else if (strcmp (prev_wd ,"ECHO_HIDDEN" )== 0 )
3640+ {
3641+ static const char * const my_list []=
3642+ {"noexec" ,"off" ,"on" ,NULL };
3643+
3644+ COMPLETE_WITH_LIST_CS (my_list );
3645+ }
3646+ else if (strcmp (prev_wd ,"HISTCONTROL" )== 0 )
3647+ {
3648+ static const char * const my_list []=
3649+ {"ignorespace" ,"ignoredups" ,"ignoreboth" ,"none" ,NULL };
3650+
3651+ COMPLETE_WITH_LIST_CS (my_list );
3652+ }
3653+ else if (strcmp (prev_wd ,"ON_ERROR_ROLLBACK" )== 0 )
3654+ {
3655+ static const char * const my_list []=
3656+ {"on" ,"off" ,"interactive" ,NULL };
3657+
3658+ COMPLETE_WITH_LIST_CS (my_list );
3659+ }
3660+ else if (strcmp (prev_wd ,"ON_ERROR_STOP" )== 0 )
3661+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3662+ else if (strcmp (prev_wd ,"QUIET" )== 0 )
3663+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3664+ else if (strcmp (prev_wd ,"SINGLELINE" )== 0 )
3665+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3666+ else if (strcmp (prev_wd ,"SINGLESTEP" )== 0 )
3667+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3668+ else if (strcmp (prev_wd ,"VERBOSITY" )== 0 )
3669+ {
3670+ static const char * const my_list []=
3671+ {"default" ,"verbose" ,"terse" ,NULL };
3672+
3673+ COMPLETE_WITH_LIST_CS (my_list );
3674+ }
36103675}
36113676else if (strcmp (prev_wd ,"\\sf" )== 0 || strcmp (prev_wd ,"\\sf+" )== 0 )
36123677COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_functions ,NULL );
@@ -4052,13 +4117,40 @@ complete_from_const(const char *text, int state)
40524117}
40534118
40544119
4120+ /*
4121+ * This function appends the variable name with prefix and suffix to
4122+ * the variable names array.
4123+ */
4124+ static void
4125+ append_variable_names (char * * * varnames ,int * nvars ,
4126+ int * maxvars ,const char * varname ,
4127+ const char * prefix ,const char * suffix )
4128+ {
4129+ if (* nvars >=* maxvars )
4130+ {
4131+ * maxvars *=2 ;
4132+ * varnames = (char * * )realloc (* varnames ,
4133+ ((* maxvars )+ 1 )* sizeof (char * ));
4134+ if (!(* varnames ))
4135+ {
4136+ psql_error ("out of memory\n" );
4137+ exit (EXIT_FAILURE );
4138+ }
4139+ }
4140+
4141+ (* varnames )[(* nvars )++ ]= psprintf ("%s%s%s" ,prefix ,varname ,suffix );
4142+ }
4143+
4144+
40554145/*
40564146 * This function supports completion with the name of a psql variable.
40574147 * The variable names can be prefixed and suffixed with additional text
4058- * to support quoting usages.
4148+ * to support quoting usages. If need_value is true, only the variables
4149+ * that have the set values are picked up.
40594150 */
40604151static char * *
4061- complete_from_variables (const char * text ,const char * prefix ,const char * suffix )
4152+ complete_from_variables (const char * text ,const char * prefix ,const char * suffix ,
4153+ bool need_value )
40624154{
40634155char * * matches ;
40644156char * * varnames ;
@@ -4067,23 +4159,34 @@ complete_from_variables(const char *text, const char *prefix, const char *suffix
40674159int i ;
40684160struct _variable * ptr ;
40694161
4162+ static const char * const known_varnames []= {
4163+ "AUTOCOMMIT" ,"COMP_KEYWORD_CASE" ,"DBNAME" ,"ECHO" ,"ECHO_HIDDEN" ,
4164+ "ENCODING" ,"FETCH_COUNT" ,"HISTCONTROL" ,"HISTFILE" ,"HISTSIZE" ,
4165+ "HOST" ,"IGNOREEOF" ,"LASTOID" ,"ON_ERROR_ROLLBACK" ,"ON_ERROR_STOP" ,
4166+ "PORT" ,"PROMPT1" ,"PROMPT2" ,"PROMPT3" ,"QUIET" ,"SINGLELINE" ,
4167+ "SINGLESTEP" ,"USER" ,"VERBOSITY" ,NULL
4168+ };
4169+
40704170varnames = (char * * )pg_malloc ((maxvars + 1 )* sizeof (char * ));
40714171
4172+ if (!need_value )
4173+ {
4174+ for (i = 0 ;known_varnames [i ]&& nvars < maxvars ;i ++ )
4175+ append_variable_names (& varnames ,& nvars ,& maxvars ,
4176+ known_varnames [i ],prefix ,suffix );
4177+ }
4178+
40724179for (ptr = pset .vars -> next ;ptr ;ptr = ptr -> next )
40734180{
4074- if (nvars >=maxvars )
4181+ if (need_value && !(ptr -> value ))
4182+ continue ;
4183+ for (i = 0 ;known_varnames [i ];i ++ )/* remove duplicate entry */
40754184{
4076- maxvars *=2 ;
4077- varnames = (char * * )realloc (varnames ,
4078- (maxvars + 1 )* sizeof (char * ));
4079- if (!varnames )
4080- {
4081- psql_error ("out of memory\n" );
4082- exit (EXIT_FAILURE );
4083- }
4185+ if (strcmp (ptr -> name ,known_varnames [i ])== 0 )
4186+ continue ;
40844187}
4085-
4086- varnames [ nvars ++ ] = psprintf ( "%s%s%s" , prefix , ptr -> name ,suffix );
4188+ append_variable_names ( & varnames , & nvars , & maxvars , ptr -> name ,
4189+ prefix ,suffix );
40874190}
40884191
40894192varnames [nvars ]= NULL ;