Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3ae1679

Browse files
committed
psql: Generic tab completion support for enum and bool GUCs.
Author: Pavel StehuleReviewed-By: Andres FreundDiscussion: 5594FE7A.5050205@iki.fi
1 parent043113e commit3ae1679

File tree

1 file changed

+97
-35
lines changed

1 file changed

+97
-35
lines changed

‎src/bin/psql/tab-complete.c

Lines changed: 97 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,15 @@ static const SchemaQuery Query_for_list_of_matviews = {
759759
" (SELECT polrelid FROM pg_catalog.pg_policy "\
760760
" WHERE pg_catalog.quote_ident(polname)='%s')"
761761

762+
#defineQuery_for_enum \
763+
" SELECT name FROM ( "\
764+
" SELECT pg_catalog.quote_ident(pg_catalog.unnest(enumvals)) AS name "\
765+
" FROM pg_catalog.pg_settings "\
766+
" WHERE pg_catalog.lower(name)=pg_catalog.lower('%s') "\
767+
" UNION ALL " \
768+
" SELECT 'DEFAULT' ) ss "\
769+
" WHERE pg_catalog.substring(name,1,%%d)='%%s'"
770+
762771
/*
763772
* This is a list of all "things" in Pgsql, which can show up after CREATE or
764773
* DROP; and there is also a query to get a list of them.
@@ -845,10 +854,13 @@ static char **complete_from_variables(const char *text,
845854
staticchar*complete_from_files(constchar*text,intstate);
846855

847856
staticchar*pg_strdup_keyword_case(constchar*s,constchar*ref);
857+
staticchar*escape_string(constchar*text);
848858
staticPGresult*exec_query(constchar*query);
849859

850860
staticvoidget_previous_words(intpoint,char**previous_words,intnwords);
851861

862+
staticchar*get_guctype(constchar*varname);
863+
852864
#ifdefNOT_USED
853865
staticchar*quote_file_name(char*text,intmatch_type,char*quote_pointer);
854866
staticchar*dequote_file_name(char*text,charquote_char);
@@ -3684,6 +3696,7 @@ psql_completion(const char *text, int start, int end)
36843696
elseif (pg_strcasecmp(prev3_wd,"SET")==0&&
36853697
(pg_strcasecmp(prev_wd,"TO")==0||strcmp(prev_wd,"=")==0))
36863698
{
3699+
/* special cased code for individual GUCs */
36873700
if (pg_strcasecmp(prev2_wd,"DateStyle")==0)
36883701
{
36893702
staticconstchar*constmy_list[]=
@@ -3694,20 +3707,6 @@ psql_completion(const char *text, int start, int end)
36943707

36953708
COMPLETE_WITH_LIST(my_list);
36963709
}
3697-
elseif (pg_strcasecmp(prev2_wd,"IntervalStyle")==0)
3698-
{
3699-
staticconstchar*constmy_list[]=
3700-
{"postgres","postgres_verbose","sql_standard","iso_8601",NULL};
3701-
3702-
COMPLETE_WITH_LIST(my_list);
3703-
}
3704-
elseif (pg_strcasecmp(prev2_wd,"GEQO")==0)
3705-
{
3706-
staticconstchar*constmy_list[]=
3707-
{"ON","OFF","DEFAULT",NULL};
3708-
3709-
COMPLETE_WITH_LIST(my_list);
3710-
}
37113710
elseif (pg_strcasecmp(prev2_wd,"search_path")==0)
37123711
{
37133712
COMPLETE_WITH_QUERY(Query_for_list_of_schemas
@@ -3717,10 +3716,34 @@ psql_completion(const char *text, int start, int end)
37173716
}
37183717
else
37193718
{
3720-
staticconstchar*constmy_list[]=
3721-
{"DEFAULT",NULL};
3719+
/* generic, type based, GUC support */
37223720

3723-
COMPLETE_WITH_LIST(my_list);
3721+
char*guctype=get_guctype(prev2_wd);
3722+
3723+
if (guctype&&strcmp(guctype,"enum")==0)
3724+
{
3725+
charquerybuf[1024];
3726+
3727+
snprintf(querybuf,1024,Query_for_enum,prev2_wd);
3728+
COMPLETE_WITH_QUERY(querybuf);
3729+
}
3730+
elseif (guctype&&strcmp(guctype,"bool")==0)
3731+
{
3732+
staticconstchar*constmy_list[]=
3733+
{"on","off","true","false","yes","no","1","0","DEFAULT",NULL};
3734+
3735+
COMPLETE_WITH_LIST(my_list);
3736+
}
3737+
else
3738+
{
3739+
staticconstchar*constmy_list[]=
3740+
{"DEFAULT",NULL};
3741+
3742+
COMPLETE_WITH_LIST(my_list);
3743+
}
3744+
3745+
if (guctype)
3746+
free(guctype);
37243747
}
37253748
}
37263749

@@ -4263,30 +4286,15 @@ _complete_from_query(int is_schema_query, const char *text, int state)
42634286
result=NULL;
42644287

42654288
/* Set up suitably-escaped copies of textual inputs */
4266-
e_text=pg_malloc(string_length*2+1);
4267-
PQescapeString(e_text,text,string_length);
4289+
e_text=escape_string(text);
42684290

42694291
if (completion_info_charp)
4270-
{
4271-
size_tcharp_len;
4272-
4273-
charp_len=strlen(completion_info_charp);
4274-
e_info_charp=pg_malloc(charp_len*2+1);
4275-
PQescapeString(e_info_charp,completion_info_charp,
4276-
charp_len);
4277-
}
4292+
e_info_charp=escape_string(completion_info_charp);
42784293
else
42794294
e_info_charp=NULL;
42804295

42814296
if (completion_info_charp2)
4282-
{
4283-
size_tcharp_len;
4284-
4285-
charp_len=strlen(completion_info_charp2);
4286-
e_info_charp2=pg_malloc(charp_len*2+1);
4287-
PQescapeString(e_info_charp2,completion_info_charp2,
4288-
charp_len);
4289-
}
4297+
e_info_charp2=escape_string(completion_info_charp2);
42904298
else
42914299
e_info_charp2=NULL;
42924300

@@ -4677,6 +4685,26 @@ pg_strdup_keyword_case(const char *s, const char *ref)
46774685
}
46784686

46794687

4688+
/*
4689+
* escape_string - Escape argument for use as string literal.
4690+
*
4691+
* The returned value has to be freed.
4692+
*/
4693+
staticchar*
4694+
escape_string(constchar*text)
4695+
{
4696+
size_ttext_length;
4697+
char*result;
4698+
4699+
text_length=strlen(text);
4700+
4701+
result=pg_malloc(text_length*2+1);
4702+
PQescapeStringConn(pset.db,result,text,text_length,NULL);
4703+
4704+
returnresult;
4705+
}
4706+
4707+
46804708
/*
46814709
* Execute a query and report any errors. This should be the preferred way of
46824710
* talking to the database in this file.
@@ -4790,6 +4818,40 @@ get_previous_words(int point, char **previous_words, int nwords)
47904818
}
47914819
}
47924820

4821+
/*
4822+
* Look up the type for the GUC variable with the passed name.
4823+
*
4824+
* Returns NULL if the variable is unknown. Otherwise the returned string,
4825+
* containing the type, has to be freed.
4826+
*/
4827+
staticchar*
4828+
get_guctype(constchar*varname)
4829+
{
4830+
PQExpBufferDataquery_buffer;
4831+
char*e_varname;
4832+
PGresult*result;
4833+
char*guctype=NULL;
4834+
4835+
e_varname=escape_string(varname);
4836+
4837+
initPQExpBuffer(&query_buffer);
4838+
appendPQExpBuffer(&query_buffer,
4839+
"SELECT vartype FROM pg_catalog.pg_settings "
4840+
"WHERE pg_catalog.lower(name) = pg_catalog.lower('%s')",
4841+
e_varname);
4842+
4843+
result=exec_query(query_buffer.data);
4844+
termPQExpBuffer(&query_buffer);
4845+
free(e_varname);
4846+
4847+
if (PQresultStatus(result)==PGRES_TUPLES_OK&&PQntuples(result)>0)
4848+
guctype=pg_strdup(PQgetvalue(result,0,0));
4849+
4850+
PQclear(result);
4851+
4852+
returnguctype;
4853+
}
4854+
47934855
#ifdefNOT_USED
47944856

47954857
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp