Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3644a63

Browse files
committed
Fix function argument tab completion for schema-qualified or quoted function names
Dean Rasheed, reviewed by Josh Kupershmidt
1 parent 539d387 commit 3644a63

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

src/bin/psql/tab-complete.c

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static bool completion_case_sensitive; /* completion is case sensitive */
142142
* 3) The items from a null-pointer-terminated list.
143143
* 4) A string constant.
144144
* 5) The list of attributes of the given table (possibly schema-qualified).
145+
* 6/ The list of arguments to the given function (possibly schema-qualified).
145146
*/
146147
#define COMPLETE_WITH_QUERY(query) \
147148
do { \
@@ -202,6 +203,31 @@ do { \
202203
matches = completion_matches(text, complete_from_query); \
203204
} while (0)
204205

206+
#define COMPLETE_WITH_FUNCTION_ARG(function) \
207+
do { \
208+
char *_completion_schema; \
209+
char *_completion_function; \
210+
\
211+
_completion_schema = strtokx(function, " \t\n\r", ".", "\"", 0, \
212+
false, false, pset.encoding); \
213+
(void) strtokx(NULL, " \t\n\r", ".", "\"", 0, \
214+
false, false, pset.encoding); \
215+
_completion_function = strtokx(NULL, " \t\n\r", ".", "\"", 0, \
216+
false, false, pset.encoding); \
217+
if (_completion_function == NULL) \
218+
{ \
219+
completion_charp = Query_for_list_of_arguments; \
220+
completion_info_charp = function; \
221+
} \
222+
else \
223+
{ \
224+
completion_charp = Query_for_list_of_arguments_with_schema; \
225+
completion_info_charp = _completion_function; \
226+
completion_info_charp2 = _completion_schema; \
227+
} \
228+
matches = completion_matches(text, complete_from_query); \
229+
} while (0)
230+
205231
/*
206232
* Assembly instructions for schema queries
207233
*/
@@ -598,10 +624,25 @@ static const SchemaQuery Query_for_list_of_views = {
598624
" FROM pg_catalog.pg_am "\
599625
" WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
600626

627+
/* the silly-looking length condition is just to eat up the current word */
601628
#define Query_for_list_of_arguments \
602-
" SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
603-
" FROM pg_catalog.pg_proc "\
604-
" WHERE proname='%s'"
629+
"SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
630+
" FROM pg_catalog.pg_proc "\
631+
" WHERE (%d = pg_catalog.length('%s'))"\
632+
" AND (pg_catalog.quote_ident(proname)='%s'"\
633+
" OR '\"' || proname || '\"'='%s') "\
634+
" AND (pg_catalog.pg_function_is_visible(pg_proc.oid))"
635+
636+
/* the silly-looking length condition is just to eat up the current word */
637+
#define Query_for_list_of_arguments_with_schema \
638+
"SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
639+
" FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "\
640+
" WHERE (%d = pg_catalog.length('%s'))"\
641+
" AND n.oid = p.pronamespace "\
642+
" AND (pg_catalog.quote_ident(proname)='%s' "\
643+
" OR '\"' || proname || '\"' ='%s') "\
644+
" AND (pg_catalog.quote_ident(nspname)='%s' "\
645+
" OR '\"' || nspname || '\"' ='%s') "
605646

606647
#define Query_for_list_of_extensions \
607648
" SELECT pg_catalog.quote_ident(extname) "\
@@ -863,13 +904,7 @@ psql_completion(char *text, int start, int end)
863904
COMPLETE_WITH_LIST(list_ALTERAGG);
864905
}
865906
else
866-
{
867-
char *tmp_buf = malloc(strlen(Query_for_list_of_arguments) + strlen(prev2_wd));
868-
869-
sprintf(tmp_buf, Query_for_list_of_arguments, prev2_wd);
870-
COMPLETE_WITH_QUERY(tmp_buf);
871-
free(tmp_buf);
872-
}
907+
COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
873908
}
874909

875910
/* ALTER SCHEMA <name> */
@@ -2186,13 +2221,7 @@ psql_completion(char *text, int start, int end)
21862221
(pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 ||
21872222
pg_strcasecmp(prev3_wd, "FUNCTION") == 0) &&
21882223
pg_strcasecmp(prev_wd, "(") == 0)
2189-
{
2190-
char *tmp_buf = malloc(strlen(Query_for_list_of_arguments) + strlen(prev2_wd));
2191-
2192-
sprintf(tmp_buf, Query_for_list_of_arguments, prev2_wd);
2193-
COMPLETE_WITH_QUERY(tmp_buf);
2194-
free(tmp_buf);
2195-
}
2224+
COMPLETE_WITH_FUNCTION_ARG(prev2_wd);
21962225
/* DROP OWNED BY */
21972226
else if (pg_strcasecmp(prev2_wd, "DROP") == 0 &&
21982227
pg_strcasecmp(prev_wd, "OWNED") == 0)

0 commit comments

Comments
 (0)