@@ -813,8 +813,11 @@ static char *_complete_from_query(int is_schema_query,
813
813
const char * text ,int state );
814
814
static char * complete_from_list (const char * text ,int state );
815
815
static 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 );
816
819
static char * * complete_from_variables (const char * text ,
817
- const char * prefix ,const char * suffix );
820
+ const char * prefix ,const char * suffix , bool need_value );
818
821
static char * complete_from_files (const char * text ,int state );
819
822
820
823
static char * pg_strdup_keyword_case (const char * s ,const char * ref );
@@ -925,11 +928,11 @@ psql_completion(const char *text, int start, int end)
925
928
else if (text [0 ]== ':' && text [1 ]!= ':' )
926
929
{
927
930
if (text [1 ]== '\'' )
928
- matches = complete_from_variables (text ,":'" ,"'" );
931
+ matches = complete_from_variables (text ,":'" ,"'" , true );
929
932
else if (text [1 ]== '"' )
930
- matches = complete_from_variables (text ,":\"" ,"\"" );
933
+ matches = complete_from_variables (text ,":\"" ,"\"" , true );
931
934
else
932
- matches = complete_from_variables (text ,":" ,"" );
935
+ matches = complete_from_variables (text ,":" ,"" , true );
933
936
}
934
937
935
938
/* If no previous word, suggest one of the basic sql commands */
@@ -3604,9 +3607,71 @@ psql_completion(const char *text, int start, int end)
3604
3607
COMPLETE_WITH_LIST_CS (my_list );
3605
3608
}
3606
3609
}
3610
+ else if (strcmp (prev_wd ,"\\unset" )== 0 )
3611
+ {
3612
+ matches = complete_from_variables (text ,"" ,"" , true);
3613
+ }
3607
3614
else if (strcmp (prev_wd ,"\\set" )== 0 )
3608
3615
{
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
+ }
3610
3675
}
3611
3676
else if (strcmp (prev_wd ,"\\sf" )== 0 || strcmp (prev_wd ,"\\sf+" )== 0 )
3612
3677
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_functions ,NULL );
@@ -4052,13 +4117,40 @@ complete_from_const(const char *text, int state)
4052
4117
}
4053
4118
4054
4119
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
+
4055
4145
/*
4056
4146
* This function supports completion with the name of a psql variable.
4057
4147
* 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.
4059
4150
*/
4060
4151
static 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 )
4062
4154
{
4063
4155
char * * matches ;
4064
4156
char * * varnames ;
@@ -4067,23 +4159,34 @@ complete_from_variables(const char *text, const char *prefix, const char *suffix
4067
4159
int i ;
4068
4160
struct _variable * ptr ;
4069
4161
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
+
4070
4170
varnames = (char * * )pg_malloc ((maxvars + 1 )* sizeof (char * ));
4071
4171
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
+
4072
4179
for (ptr = pset .vars -> next ;ptr ;ptr = ptr -> next )
4073
4180
{
4074
- if (nvars >=maxvars )
4181
+ if (need_value && !(ptr -> value ))
4182
+ continue ;
4183
+ for (i = 0 ;known_varnames [i ];i ++ )/* remove duplicate entry */
4075
4184
{
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 ;
4084
4187
}
4085
-
4086
- varnames [ nvars ++ ] = psprintf ( "%s%s%s" , prefix , ptr -> name ,suffix );
4188
+ append_variable_names ( & varnames , & nvars , & maxvars , ptr -> name ,
4189
+ prefix ,suffix );
4087
4190
}
4088
4191
4089
4192
varnames [nvars ]= NULL ;