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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy