Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nELV5-0005mM-94 for pgsql-hackers@arkaria.postgresql.org; Mon, 31 Jan 2022 01:28:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nELV3-0002f2-GM for pgsql-hackers@arkaria.postgresql.org; Mon, 31 Jan 2022 01:28:57 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nELV2-0002er-IA for pgsql-hackers@lists.postgresql.org; Mon, 31 Jan 2022 01:28:57 +0000 Received: from out5-smtp.messagingengine.com ([66.111.4.29]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nELUv-00085n-K5 for pgsql-hackers@lists.postgresql.org; Mon, 31 Jan 2022 01:28:55 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 783DE5C00F0; Sun, 30 Jan 2022 20:28:48 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Sun, 30 Jan 2022 20:28:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ilmari.org; h=cc :cc:content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; bh=GBPFiyZqK6/yeM+5sxnlOr28nTm95uDRIlvh4s bPfmM=; b=iRkgU2K7OdRvOWNRqbgd3p382nJ+nTsT2Gde/Nl8tLlt6dfu3nlp1G rpeMKSb9OYUQNATR3Lr7aaLhDU/tCNZ0MBmhJQ3x7PXf1exZY4qraBuN6yi6Al9H tOxaciwdtkg9w+8TrFsF+RIuo0cX8enfR76tL10KcL2GB4diCx/rf2Ghp867214F PuR9NK6gu/FJrZxJlwvFh8sWKukKORiMaconklwNMAFM1Uo+42y8TvdMuHz0FjsW +8C/J9PvB2d52Y0zzLliEUclM6+BJbkeBBkoUJK/uZZsgBII+ZdNt+XrsTgnvNlj I61c21bshF/EHMpuICBsbfzKu0crpx+w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=GBPFiyZqK6/yeM+5s xnlOr28nTm95uDRIlvh4sbPfmM=; b=mLNBDrT0XKSAw9GkrkVZbrW5yNZvzrokd bfTaDy+16bvWD/vcrrn+wLlz+tR+g9FrI3saJ6JzTVYZ2s1KKPN/MOlqh78QPs9D Eg7zugAI1LO17pVqi3qQCJ4Wa1LND3RrEj1oFgfpZkPu4zREEjMqeMrIvqaXb5gq qA7L4LmgkhvBJ7zt4rT0/oLPmC4kK3VMP/Cx9dXh6nK7fBsFJTbx9ItaQLVHVZBE SbqqUy3iyP+7XZAUhfg/woq41yVVFwFiv0LKloUIeg5OWfQZLqWwgQtUsc03bkUj ZKJpCfge/+F5E7n2sHXwzO34ekrqy21I+964daZ/9gQg5K2faZrAA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrgedtgdeffecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufhffjgfkfgggtgesmhdtreertderjeenucfhrhhomhepffgrghhfihhn nhgpkfhlmhgrrhhipgforghnnhhsnohkvghruceoihhlmhgrrhhisehilhhmrghrihdroh hrgheqnecuggftrfgrthhtvghrnhepteevieehteetleeglefghfefkeejheelledttedt gfdvkeffheffvdekheeuudffnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomhepihhlmhgrrhhisehilhhmrghrihdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 30 Jan 2022 20:28:47 -0500 (EST) From: =?utf-8?Q?Dagfinn_Ilmari_Manns=C3=A5ker?= To: Tom Lane Cc: "tanghy.fnst@fujitsu.com" , Peter Eisentraut , Japin Li , Kyotaro Horiguchi , Laurenz Albe , "smithpb2250@gmail.com" , "david.zhang@highgo.ca" , "pgsql-hackers@lists.postgresql.org" Subject: Re: Support tab completion for upper character inputs in psql References: <80b093ae-88bd-8d8a-68b9-b535a3ab11be@enterprisedb.com> <54bd7839-f463-ef03-f2d2-ccb8184b9b27@enterprisedb.com> <1068530.1641480996@sss.pgh.pa.us> <3547066.1642272686@sss.pgh.pa.us> <2304294.1643152287@sss.pgh.pa.us> <2645164.1643315022@sss.pgh.pa.us> <2771362.1643385796@sss.pgh.pa.us> <2805502.1643405157@sss.pgh.pa.us> <2818574.1643408192@sss.pgh.pa.us> <324281.1643567679@sss.pgh.pa.us> Date: Mon, 31 Jan 2022 01:28:45 +0000 In-Reply-To: <324281.1643567679@sss.pgh.pa.us> (Tom Lane's message of "Sun, 30 Jan 2022 13:34:39 -0500") Message-ID: <8735l41ynm.fsf@wibble.ilmari.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=-=-= Content-Type: text/plain Tom Lane writes: > "tanghy.fnst@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 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Respect-COMP_KEYWORD_CASE-for-additional-keywords.patch From 7b278ea5c48d386e1c6f277f3d94520505205cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= 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 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-psql-tab-complete-remove-unnecessary-null-checks.patch From f4d38e9a819fa8650bea201784511654ec1d858e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= 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 --=-=-=--