From c6eda875bd53404c1e4f1bf628d683bccebb564a Mon Sep 17 00:00:00 2001 From: Haiying Tang Date: Mon, 22 Mar 2021 20:53:50 +0900 Subject: [PATCH] Support tab completion with a query result for upper character inputs in psql diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index b67f4ea609..1f770a0295 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -197,18 +197,21 @@ static bool completion_force_quote; /* true to force-quote filenames */ */ #define COMPLETE_WITH_QUERY(query) \ do { \ + completion_case_sensitive = false; \ completion_charp = query; \ matches = rl_completion_matches(text, complete_from_query); \ } while (0) #define COMPLETE_WITH_VERSIONED_QUERY(query) \ do { \ + completion_case_sensitive = false; \ completion_vquery = query; \ matches = rl_completion_matches(text, complete_from_versioned_query); \ } while (0) #define COMPLETE_WITH_SCHEMA_QUERY(query, addon) \ do { \ + completion_case_sensitive = false; \ completion_squery = &(query); \ completion_charp = addon; \ matches = rl_completion_matches(text, complete_from_schema_query); \ @@ -216,6 +219,7 @@ do { \ #define COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(query, addon) \ do { \ + completion_case_sensitive = false; \ completion_squery = query; \ completion_vquery = addon; \ matches = rl_completion_matches(text, complete_from_versioned_schema_query); \ @@ -1016,7 +1020,7 @@ static const VersionedQuery Query_for_list_of_subscriptions[] = { }; /* - * This is a list of all "things" in Pgsql, which can show up after CREATE or + * This is a list of all "things" in pgsql, which can show up after CREATE or * DROP; and there is also a query to get a list of them. */ @@ -1167,6 +1171,7 @@ static char *complete_from_files(const char *text, int state); static char *pg_strdup_keyword_case(const char *s, const char *ref); static char *escape_string(const char *text); +static char *pg_string_tolower(const char *text); static PGresult *exec_query(const char *query); static char **get_previous_words(int point, char **buffer, int *nwords); @@ -4402,8 +4407,10 @@ _complete_from_query(const char *simple_query, PQclear(result); result = NULL; - /* Set up suitably-escaped copies of textual inputs */ - e_text = escape_string(text); + /* Set up suitably-escaped copies of textual inputs, + * then change the textual inputs to lower case. + */ + e_text = pg_string_tolower(escape_string(text)); if (completion_info_charp) e_info_charp = escape_string(completion_info_charp); @@ -4446,7 +4453,7 @@ _complete_from_query(const char *simple_query, */ if (strcmp(schema_query->catname, "pg_catalog.pg_class c") == 0 && - strncmp(text, "pg_", 3) != 0) + strncmp(pg_string_tolower(text), "pg_", 3) != 0) { appendPQExpBufferStr(&query_buffer, " AND c.relnamespace <> (SELECT oid FROM" @@ -4538,7 +4545,17 @@ _complete_from_query(const char *simple_query, while (list_index < PQntuples(result) && (item = PQgetvalue(result, list_index++, 0))) if (pg_strncasecmp(text, item, byte_length) == 0) - return pg_strdup(item); + { + if (completion_case_sensitive) + return pg_strdup(item); + else + /* + * If case insensitive matching was requested initially, + * adjust the case according to setting. + */ + return pg_strdup_keyword_case(item, text); + } + } /* If nothing matches, free the db structure and return null */ @@ -4589,7 +4606,6 @@ complete_from_list(const char *text, int state) if (completion_case_sensitive) return pg_strdup(item); else - /* * If case insensitive matching was requested initially, * adjust the case according to setting. @@ -4642,7 +4658,6 @@ complete_from_const(const char *text, int state) if (completion_case_sensitive) return pg_strdup(completion_charp); else - /* * If case insensitive matching was requested initially, adjust * the case according to setting. @@ -4875,6 +4890,24 @@ escape_string(const char *text) } +/* + * pg_string_tolower - Fold a string to lower case. + */ +static char * +pg_string_tolower(const char *text) +{ + char *ret, + *p; + + ret = pg_strdup(text); + + for (p = ret; *p; p++) + *p = pg_tolower((unsigned char) *p); + + return ret; +} + + /* * Execute a query and report any errors. This should be the preferred way of * talking to the database in this file. -- 2.30.0.windows.2