Tom Lane <t...@sss.pgh.pa.us> writes: > "tanghy.f...@fujitsu.com" <tanghy.f...@fujitsu.com> writes: >> Thanks for your V16 patch, I tested it. >> The results LGTM. > > Pushed, thanks for looking.
I wasn't following this thread, but I noticed a few small potential improvements when I saw the commit. First, as noted in the test, it doesn't preserve the case of the input for keywords appended to the query result. This is easily fixed by using `pg_strdup_keyword_case()`, per the first attached patch. The second might be more of a matter of style or opinion, but I noticed a bunch of `if (foo) free(foo);`, which is redundant given that `free(NULL)` is a no-op. To simplify the code further, I also made `escape_string(NULL)` be a no-op, returning `NULL`. - ilmari
>From 7b278ea5c48d386e1c6f277f3d94520505205cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilm...@ilmari.org> Date: Mon, 31 Jan 2022 00:42:00 +0000 Subject: [PATCH 1/2] Respect COMP_KEYWORD_CASE for additional keywords When tacking on keywords to the result of a completion query, use pg_strdup_keyword_case(). --- src/bin/psql/t/010_tab_completion.pl | 26 ++++++++++++++++++++------ src/bin/psql/tab-complete.c | 4 ++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl index c4f6552ac9..c4a1d5e1bc 100644 --- a/src/bin/psql/t/010_tab_completion.pl +++ b/src/bin/psql/t/010_tab_completion.pl @@ -317,12 +317,26 @@ sub clear_line clear_line(); -# check completion of a keyword offered in addition to object names -# (that code path currently doesn't preserve case of what's typed) -check_completion( - "comment on constraint foo on dom\t", - qr|DOMAIN|, - "offer keyword in addition to query result"); +foreach ( + ['lower', 'DOM', 'domain'], + ['upper', 'dom', 'DOMAIN'], + ['preserve-lower', 'dom', 'domain'], + ['preserve-upper', 'DOM', 'DOMAIN'], +) { + my ($case, $in, $out) = @$_; + + # check completion of a keyword offered in addition to object names + # and obeys COMP_KEYWORD_CASE + check_completion( + "\\set COMP_KEYWORD_CASE $case\n", + qr/postgres=#/, + "set completion case to '$case'"); + check_completion( + "comment on constraint foo on $in\t", + qr|$out|, + "offer keyword in addition to query result (COMP_KEYWORD_CASE=$case)"); + clear_line(); +} clear_query(); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index b2ec50b4f2..0c7a99be0a 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -5032,7 +5032,7 @@ _complete_from_query(const char *simple_query, if (pg_strncasecmp(text, item, strlen(text)) == 0) { num_other++; - return pg_strdup(item); + return pg_strdup_keyword_case(item, text); } } } @@ -5050,7 +5050,7 @@ _complete_from_query(const char *simple_query, if (pg_strncasecmp(text, item, strlen(text)) == 0) { num_other++; - return pg_strdup(item); + return pg_strdup_keyword_case(item, text); } } } -- 2.30.2
>From f4d38e9a819fa8650bea201784511654ec1d858e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= <ilm...@ilmari.org> Date: Mon, 31 Jan 2022 00:09:14 +0000 Subject: [PATCH 2/2] psql tab-complete: remove unnecessary null checks free(NULL) is specified to be a no-op, so no need to check before calling it. Also make escape_string(NULL) a no-op to match. --- src/bin/psql/tab-complete.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 0c7a99be0a..5115f02934 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -4555,11 +4555,9 @@ psql_completion(const char *text, int start, int end) free(previous_words); free(words_buffer); free(text_copy); - if (completion_ref_object) - free(completion_ref_object); + free(completion_ref_object); completion_ref_object = NULL; - if (completion_ref_schema) - free(completion_ref_schema); + free(completion_ref_schema); completion_ref_schema = NULL; /* Return our Grand List O' Matches */ @@ -4790,21 +4788,9 @@ _complete_from_query(const char *simple_query, * up suitably-escaped copies of all the strings we need. */ e_object_like = make_like_pattern(objectname); - - if (schemaname) - e_schemaname = escape_string(schemaname); - else - e_schemaname = NULL; - - if (completion_ref_object) - e_ref_object = escape_string(completion_ref_object); - else - e_ref_object = NULL; - - if (completion_ref_schema) - e_ref_schema = escape_string(completion_ref_schema); - else - e_ref_schema = NULL; + e_schemaname = escape_string(schemaname); + e_ref_object = escape_string(completion_ref_object); + e_ref_schema = escape_string(completion_ref_schema); initPQExpBuffer(&query_buffer); @@ -4959,12 +4945,9 @@ _complete_from_query(const char *simple_query, /* Clean up */ termPQExpBuffer(&query_buffer); free(e_object_like); - if (e_schemaname) - free(e_schemaname); - if (e_ref_object) - free(e_ref_object); - if (e_ref_schema) - free(e_ref_schema); + free(e_schemaname); + free(e_ref_object); + free(e_ref_schema); } /* Return the next result, if any, but not if the query failed */ @@ -5401,6 +5384,7 @@ pg_strdup_keyword_case(const char *s, const char *ref) * escape_string - Escape argument for use as string literal. * * The returned value has to be freed. + * Returns NULL if called with NULL. */ static char * escape_string(const char *text) @@ -5408,6 +5392,9 @@ escape_string(const char *text) size_t text_length; char *result; + if (!text) + return text; + text_length = strlen(text); result = pg_malloc(text_length * 2 + 1); -- 2.30.2